AngularJS : Access radio button value change in controller - javascript

I have a few radio buttons with certain value. What I'm trying to achieve is, on selecting certain radio buttons, it's value should add up and be displayed as total.
Here is my AngularJS directive and controller code :
angular.module('mapp',[])
.controller('ctrl',['$scope',function($scope){
$scope.items = [
{'Id':1, 'Cost':100},
{'Id':2,'Cost':200}
];
$scope.total = 0;
}])
.directive('customElement',function(){
return {
restrict: 'E',
scope:{
data: '=info'
},
template: '<input type="radio" ng-model="data">\
<span>{{data}}</span>'
}
});
And here is the HTML code:
<div ng-app="mapp">
<div ng-controller="ctrl">
<custom-element ng-repeat="item in items" info="item.Cost"></custom-element>
<br/>
<br/> Total: <span>{{total}}</span>
</div>
</div>
And here is a DEMO.

You can do that by passing in two different arguments to the directive: data (for the label) and then a secondary boolean selected to determine whether the item is selected or not.
Javascript:
angular.module('mapp',[])
.controller('ctrl',['$scope',function($scope){
$scope.items = [
{'Id':1, 'Cost':100, selected: false},
{'Id':2,'Cost':200, selected: false}
];
$scope.total = function () {
var selectedItems = $scope.items.filter(function (d) { return d.selected; });
console.log('items = ', $scope.items);
var totalSum = 0;
selectedItems.forEach(function (item) {
totalSum += item['Cost'];
});
return totalSum;
};
}])
.directive('customElement',function(){
return {
restrict: 'E',
scope:{
data: '=info',
selected: '=selected'
},
template: '<input type="radio" ng-model="selected" ng-value="true">\
<span>{{data}}</span>'
}
});
HTML:
<custom-element ng-repeat="item in items"
info="item.Cost"
selected="item.selected">
</custom-element>
Finally, you'll need to calculate the total via a getter.
Demo: http://jsfiddle.net/vv46xs0c/

I haven't succeeded with radio buttons (I don't know much about this thing :-(, and I could not "uncheck" the radio buttons ), but I've succeeded with checkboxes
Here is your updated fiddle : http://jsfiddle.net/8kpddb92/4/
What did I have to change :
ng-model needed a boolean
adding a function inside your controller
$scope.handleChange = function(){
$scope.total = 0;
for (var i=0; i < $scope.items.length; i++){
if ($scope.items[i].isSelected)
$scope.total += $scope.items[i].Cost;
}
}
And calling this function inside the child directive :
template: '<input type="checkbox" ng-model="data.isSelected" ng-change=$parent.handleChange()>\
<span>{{data.Cost}}</span>'

No need to make a new scope. Just use the 'item' from the repeat. Call a change function on click, pass the item, and you are good to go :)
angular.module('mapp',[])
.controller('ctrl',['$scope',function($scope){
$scope.items = [
{'Id':1, 'Cost':100},
{'Id':2,'Cost':200}
];
$scope.total = 0;
$scope.change = function(item) {
$scope.total = item.Cost;
};
}])
.directive('customElement',function(){
return {
restrict: 'E',
template: '<input type="radio" name="radios" ng-click="change(item)"><span>{{item.Cost}}</span>'
}
});

Related

how to iterate through checkbox object

I have three checkboxes:-
<label>Type:</label>
<label>one</label>
<input type="checkbox" name="type" ng-model="a.Type[0]"/>
<label>two</label>
<input type="checkbox" name="type" ng-model="a.Type[1]"/>
<label>three</label>
<input type="checkbox" name="type" ng-model="a.Type[2]"/>
These checkboxes are stored in the backend as an array of string.
My value is displaying in:-
<li class="list-group-item"><strong>Type</strong>: <span ng-repeat="values in myArray">{{values}}</span></li>
My directive code is:-
(function () {
'use strict';
angular.module('myApp.components')
.directive('abc', abc);
abc.$inject = ['$http', '$timeout', 'ApiServices'];
function abc($http, $timeout, ApiServices) {
return {
restrict: 'EA',
scope: {
},
link: function (scope, el, attrs) {
scope.a = {};
$('#abc').on('hide.bs.modal', function () {
scope.active = false;
});
$('#abc').on('shown.bs.modal', function () {
scope.active = true;
scope.myArray = [];
scope.iterate = function () {
for (var key in scope.a.Type) {
if (scope.a.Type.hasOwnProperty(key)) {
scope.myArray.push(scope.a.Type[key]);
}
}
};
scope.iterate();
},
templateUrl: ''
};
}
})();
Here what I am trying to do is- I want to iterate through 'Type' checkboxes and pushed the values in 'myArray', and then display only the values.
Probably, my example below is somewhat similar to what you are looking for:
HTML:
<span>Select Type:</span>
<div ng-repeat="type in myArray">
<input type="checkbox" ng-model="type.value" /> {{type.type}}
</div>
<span>Selected Types:</span>
<div ng-repeat="type in myArray">
<span ng-show="type.value"> {{type.type}}</span>
</div>
JS:
$scope.a = {};
$scope.a.Type = ["One","Two","Three"]; // your string array
$scope.myArray = [];
$scope.a.Type.forEach(function(item){
$scope.myArray.push({type: item, value: false }); // create new array to make it selectable via checkbox
});
I guess, you no more need your directive now. The iteration and filtering is done in HTML itself.
I hope this helps.

Custom directive not firing up

I have a directive that makes some value prices validation, and I thought that it was working well, until I notice a bug, for example if the next value price I'm validating in the input is the same of the previous one, the next one is not validated, I don't understand why, if it was different value it worked with no issues, but if the value is the same of the previous, the directive is not fired up, I have no idea if there is any relation with the '$asyncValidators', above I leave my custom directive.
Directive:
(function() {
'use strict';
angular
.module('myApp')
.directive('priceValidator', priceValidator);
priceValidator.$inject = ['$q', 'ServerValidatorService'];
/* #ngInject */
function priceValidator($q, ServerValidatorService) {
var directive = {
link: link,
restrict: 'A',
require: 'ngModel',
scope: {
costPrice: '=',
currentPvp: '='
}
};
return directive;
function link(scope, element, attrs, ctrl) {
ctrl.$asyncValidators.costPrice = function(costPrice) {
var pvp = scope.currentPvp;
scope.currentPrice = costPrice;
var cost = String(costPrice).replace(",", ".");
return ServerValidatorService.validateCostPrice(pvp, cost)
.then(function() {
return true;
},
function(response) {
ctrl.$setDirty();
if (response.data.errors.maximum[0])
scope.costPrice = response.data.errors.maximum[0];
return $q.reject(response.data.message);
});
};
}
}
})();
// Controller function that fill form with each product info:
function getMainProduct(productLine) {
if (typeof productLine !== "undefined") {
vm.discountId = productLine.discount_id;
vm.discountPercentage = productLine.discount_percentage;
vm.valuePrice = productLine.value_price;
}
}
HTML
<input type="text" class="form-control"
name="discount" ng-model="form.discPrice"
ng-model-options="{updateOn: 'default blur', debounce: {'default': 300, 'blur': 0} }"
ng-required="formCtrl.isP()" cost-price="form.maxP"
current-pvp="form.pvp" num-type="decimal"
ng-change="formCtrl.check()" price-validator>

Validating custom component in angular 1.5

I was working in angular project, There I had come across a situation in which I need to validate custom component having a textbox.
<dollar-text-validate ng-model="ctrl.value" required name="myDir"></dollar-text-validate>
My Component
angular.module("myApp", []);
angular.module("myApp").controller('MyController',function(){
var ctrl = this;
ctrl.value = 56;
});
angular.module("myApp").component('dollarTextValidate',{
bindings: {
ngModel :'='
},
template: '<div><input type="text" ng-focus="ctrl.focus()" ng-blur="ctrl.blur()" ng-model="ctrl.amount1"><input type="hidden" ng-model="ctrl.ngModel"></div>',
controller: function() {
var ctrl = this;
// ctrl.amount1 =
ctrl.amount1 =ctrl.ngModel===undefined||ctrl.ngModel==='' ? '' :'$'+ctrl.ngModel;
console.log(ctrl.ngModel);
ctrl.focus=function(){
ctrl.amount1 = ctrl.amount1 === undefined ? '' : ctrl.amount1.slice(1);
ctrl.ngModel = ctrl.amount1;
console.log(ctrl.ngModel);
}
ctrl.blur=function(){
ctrl.ngModel = ctrl.amount1;
ctrl.amount1 = ctrl.amount1==='' ? '' :'$'+ctrl.ngModel;
console.log(ctrl.ngModel);
}
},
controllerAs:'ctrl'
})
This component is used to set $ symbol in front of entered value. So $ appended value will be available in textbox and original value which is to be validated in hidden field.
How can I validate hidden field. I tried with required attribute in hidden tag but nothing happening. Also tried with custom tag.
Sorry to break it to you, but you might wanna go for directive, and then use $parsers, $formatter and $validators properties of ngModelController.
Component can be used for this, but it is just easier with normal directive.
angular.module('myApp', []);
angular.module("myApp").directive('dollarTextValidate', function() {
return {
require: 'ngModel',
link: function($scope, $element) {
var regexp = /^\$(\d+(\.\d+)?)$/;
var ngModel = $element.controller('ngModel');
ngModel.$formatters.push(function(value) {
return value ? '$' + value : '';
});
ngModel.$parsers.push(function(value) {
var matched = value.match(regexp);
if (matched) {
return +matched[1];
}
});
ngModel.$validators.greaterThan10 = function (modelVal, viewVal) {
var value = modelVal || viewVal;
return value > 10;
};
},
controllerAs: 'ctrl'
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<div ng-app="myApp" ng-form="form">
dollar-text-validate = <input dollar-text-validate ng-model="value" required name="myDir"><br>
number input = <input type="number" ng-model="value" required><br>
value = {{value}}<br>
errors = {{form.myDir.$error}}
</div>

AngularJS Add More Option For Input Type File

Suppose I want to add 'Add More' button next to input type file field.
So that on click of 'Add More' button one more file field will be created.
I could use '.clone()' for this in JQuery.
But how will I do this in AngularJS?
Thanks!!
In controller:
$scope.addMore = function() {
$scope.inputs += 1;
};
$scope.range = function(count) {
var inputs = [];
for (var i = 0; i < count; i++) {
inputs.push(i)
}
return inputs;
}
$scope.inputs = 0;
In HTML:
<input ng-repeat="n in range(inputs)">
<button ng-click="addMore()">Add more!</button>
MORE USEFUL VERSION:
Typically you want to have other information related to the input field though, so depending on your use case, you might just want to have an array of input objects with some properties, and then ng-repeat over that array like following:
Controller:
$scope.inputs = [];
$scope.addMore = function() {
$scope.inputs.push({
id: $scope.inputs.length,
text: "Initial text here"
})
};
HTML:
<input ng-repeat="input in inputs" ng-model="inputs[$index].text">
<button ng-click="addMore()">Add more!</button>
What you want to do is to create an array of input button.
display your input array :
<div ng-repeat="item in items"><input type="text" ng-model="item.value"><div>
attach a function to the ng-click of your button :
<button ng-click="addMore()">Add More</button>
and then define your array in controller :
$scope.items = [];
$scope.addMore = function () {
$scope.items.push({
value:'default'
});

binding data with ui-jq slider in angular

I have a page where users can rate their performance in different categories. I am using the ui-jq slider for angular and i want to bind the selected value to a model in $scope.
<div ng-repeat="competence in screening_has_skillset.skillset.competences">
<div class="col-sm-12 m-b-md">
<p class="h3">{{competence.competence.name}}</p>
{{competence.competence.level}}
<input id="slider"
ui-jq="slider"
ui-options="{
min: 0,
max: 10,
step: 1,
value: {{competence.competence.level || val }}
}"
ng-model="competence.competence.level"
class="slider slider-horizontal form-control" type="text">
</div>
</div>
I had same problem and write an attribute directive which is named as ng-slider-model for value binding.
.directive('ngSliderModel', ['$parse', function($parse) {
return {
scope: {
ngSliderModel: '=',
uiOptions: '='
},
restrict: 'A',
required: ['ngSliderModel'],
link: function(scope, element, attrs) {
// check there is uiOption or not
var options = ('uiOptions' in attrs) ? scope.uiOptions : {};
// get the value of ngSlider Model
var val = scope.ngSliderModel;
// if value is range [15,25] then return values for uiOptions propertyName else value for singles
var propName = (angular.isArray(val)) ? 'values' : 'value';
/* if you want to slide when the scope value changed not from slider...
watch the ngSliderModel attribute
*/
scope.$watch('ngSliderModel', function(newValue) {
element.slider(propName, newValue);
});
// set value for options
options[propName] = val;
// binding slide event
element.bind('slide', function() {
// Read the current value
var value = element.slider('option', propName);
scope.$apply(function() {
// Apply the value to scope
scope.ngSliderModel = value;
});
});
}
};
}]);;
<input id="slider" ui-jq="slider" value="val" ui-options="{
min: 1,
max: 100,
step: 1,
value: val
}" ui-event="{slideStop: 'updateModel($event)'}" class="slider slider-horizontal form-control" type="text">
value = "val"
do this. in your html element input set the value. where val is scope variable

Categories