AngularJs Directive get radio button ng-model value on change - javascript

I have created an Angular js Directive that loops through ng-repeat and if users chooses any of those radio button, it should alert the current ng-model value.
But its not working. Please help.
var someapp = angular.module('someapp', []);
someapp.controller('someappCtrl', function($scope, $http) {
//...
}).directive('checkthemChoice', function() {
return {
restrict: 'A',
template: '<label ng-repeat="choice in choices" for="{{ choice }}"><input type="radio" ng-checked="$first" name="selecttable" ng-model="radioSelected" value="{{ choice }}" id="{{ choice }}"> {{ choice }}</label>',
link: function(scope, element, attrs) {
scope.choices = ['organization', 'user'];
element.on('change', function() {
//this selected the parent DIV checkthem
//but I want select the radio input inside LABEL
});
scope.$watch('radioSelected', function(val) {
//this doesnt work
alert(val);
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="someapp" ng-controller="someappCtrl">
<div class="checkthem" checkthem-Choice=""></div>
</div>

This works.
radioSelected needs to be a property of an object (for example, test). The explanation is given here https://github.com/angular/angular.js/wiki/Understanding-Scopes
Also, I have a put a test for undefined in the watch to avoid the first alert on load.
var someapp = angular.module('someapp', []);
someapp.controller('someappCtrl', function($scope, $http) {
//...
}).directive('checkthemChoice', function() {
return {
restrict: 'A',
template: '<label ng-repeat="choice in choices" for="{{ choice }}"><input type="radio" ng-checked="$first" name="selecttable" ng-model="test.radioSelected" value="{{ choice }}" id="{{ choice }}"> {{ choice }}</label>',
link: function(scope, element, attrs) {
scope.choices = ['organization', 'user'];
scope.test = {};
element.on('change', function() {
//this selected the parent DIV checkthem
//but I want select the radio input inside LABEL
});
scope.$watch('test.radioSelected', function(val) {
if (val !== undefined) alert(val);
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="someapp" ng-controller="someappCtrl">
<div class="checkthem" checkthem-Choice=""></div>
</div>

Related

Disable AngularJS dropdown multiselect

I have a directive to disable the angularjs dropdown multiselect, this directive working properly when change the checkbox but it's not working when init the control, I want to disable the dropdown by the value that is passed to the directive when start the controller.
that's the directive:
var FormModule = angular.module('FormModule', []);
FormModule.directive('ngDropdownMultiselectDisabled', function () {
return {
restrict: 'A',
controller: function ($scope, $element, $attrs) {
var $btn;
$btn = $element.find('button');
return $scope.$watch($attrs.ngDropdownMultiselectDisabled, function (newVal) {
return $btn.attr('disabled', newVal);
});
}
};
});
and that's the div of the dropdown:
<div class="col-sm-3">
<input id="chkHasParent" type="checkbox" class="form-control"
ng-model="property.HasParent" ng-checked="property.HasParent==true" />
<label for="chkHasParent" class="lblCheck">Has Parent</label>
</div>
<div class="col-sm-3">
<label>Parent Property</label>
<div id="ddlParentProperty" ng-dropdown-multiselect=""
options="Properties" selected-model="parentPropertyModel"
extra-settings="settingParentProperty"
ng-dropdown-multiselect-disabled="!property.HasParent">
</div>
</div>
and thats the docs of the Angular js dropdown multiselect if anyone does not know it.
$scope.hasParentChange = function hasParentChange(hasParent) {
if (hasParent != null) {
if (hasParent == false) {
document.getElementById("ddlParentProperty").getElementsByTagName('button')[0].setAttribute("disabled", "disabled");
}
else {
document.getElementById("ddlParentProperty").getElementsByTagName('button')[0].removeAttribute("disabled");
}
}
else {
document.getElementById("ddlParentProperty").getElementsByTagName('button')[0].setAttribute("disabled", "disabled");
}
}
angular.element(document).ready(function () {
$scope.hasParentChange($scope.property.HasParent)
});

Focus on empty ng-model data after ng-readonly=true

I have a form input. When the page is loaded the input has "ng-readonly=true" property and it only shows the data.
When I double click (ng-dblclick) the property "ng-readonly" changes to false and I can edit the input.
For all this, it is working currectly. But when the data
(ng-model="school.fax") a row data is empty it does do a focus, and I need to click on the input to focus and start writing.
It does not happen when the data is not empty (ng-model="school.fax" have value, get value from server API) and in this case, it's working correctly
The question:
How can I focus on the empty input and start writing without need to click the input row?
The code:
HTML
<label>
<input class="inputs"
type="text"
ng-readonly="!edit_school_fax"
ng-dblclick="editSchoolFax(true)"
ng-model="school.fax"/>
</label>
JS
$scope.editSchoolFax = function(edit) {
$scope.edit_school_fax = edit;
};
FYI
I try, and it does not work for me:
Add "autofocus" inside the input
<input autofocus
Use directive like this solution: LINK
add custom directive
link(scope, element, attrs) {
scope.$watch(attrs.someAttrs, (newVal, oldVal) => {
if (newVal === true && newVal !== oldVal) {
$timeout(() => {
element
.focus()
.select();
});
}
});
},
Use a custom directive that adds a focus method to the ngModelController:
app.directive("inputFormFocus", function() {
return {
require: "ngModel",
link: postLink
};
function postLink (scope, elem, attrs, ngModel) {
console.log("postLink");
console.log(ngModel);
ngModel.focus = function() {
elem[0].focus();
}
}
})
Usage
<form name="form1">
<input input-form-focus
name="fax"
class="inputs"
type="text"
ng-readonly="!edit_school_fax"
ng-dblclick="editSchoolFax(true)"
ng-model="school.fax"/>
</form>
$scope.form1.fax.focus();
The DEMO
angular.module("app",[])
.controller("ctrl",function($scope){
$scope.editSchoolFax = function(edit) {
$scope.edit_school_fax = edit;
};
$scope.school = { fax: "555-100-1234" };
$scope.faxFocus = function() {
$scope.edit_school_fax = true;
$scope.form1.fax.focus();
};
})
.directive("inputFormFocus", function() {
return {
require: "ngModel",
link: postLink
};
function postLink (scope, elem, attrs, ngModel) {
ngModel.focus = function() {
console.log(attrs.name + " focus");
elem[0].focus();
}
}
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl">
<form name="form1">
<input input-form-focus
name="fax"
class="inputs"
type="text"
ng-readonly="!edit_school_fax"
ng-dblclick="editSchoolFax(true)"
ng-model="school.fax"/>
</form>
<button ng-click="faxFocus()">Focus and Edit</button>
</body>

Angular 1 - toggle radio button

I need to make a radio button toggle when user click. Is more then 2 buttons.
So, when I click one button if this is selected will no longer be. If is not must be selected.
I try this, but is not works:
app.directive('toggleRadio', function($timeout) {
return {
restict: 'A',
link: function(scope, el, attrs) {
var radioState;
el.on('click', function(){
if (radioState === this) {
this.checked = false;
radioState = null;
} else {
radioState = this;
}
scope.$apply();
});
}
}
It's not require to be a directive... Thanks.
Since it's a single radio button and as you said It's not required to be a directive, which doesn't seem to be necessary as well, then you can do something like below:
var app = angular.module('app', []);
app.controller('MainCtrl', ['$scope', function($scope) {
$scope.checked = false;
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="MainCtrl">
<input type="radio" ng-model="checked"
ng-value="true" ng-click="checked=!checked" />
{{checked}}
</div>
</div>
Updated:
Ideally, you should use checkboxes for such requirement, but if it so necessary to use radio, then do it like below:
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.valChanged = false;
$scope.checked = "b";
$scope.toggle = function() {
if (!$scope.valChanged) {
$scope.checked = "";
}
$scope.valChanged = false;
}
});
<script src="https://code.angularjs.org/1.5.2/angular.js"></script>
<div ng-app="app">
<div ng-controller="MainCtrl">
<br>
<input type="radio" ng-model="checked" value="a"
ng-change="valChanged = true" ng-click="toggle()" />Option A
<br>
<input type="radio" ng-model="checked" value="b"
ng-change="valChanged = true" ng-click="toggle()" />Option B
<br>
<input type="radio" ng-model="checked" value="c"
ng-change="valChanged = true" ng-click="toggle()" />Option C
<hr> {{checked}}
</div>
</div>
I choose to create this directive:
myApp.directive('toggleRadio', [function(){
return {
restrict: 'A',
link: function(scope, el, attrs) {
el.on("mouseenter", function(e){
scope.radioStr = e.target.checked;
console.log('scope.radioStr hover: ', scope.radioStr);
});
el.on("click", function(e){
if(scope.radioStr) {
e.target.checked = false;
scope.radioStr = false;
}
else {
e.target.checked = true;
scope.radioStr = true;
}
});
}
}
}]);
And in HTML I have:
With this approach it will works just when user clicks on input itself, not for label. If somebody wants that, must rewrite this directive to find input status with, el.find(), el.next() etc.
Thanks everyone, all your informations help me to understand what've done!

Manually set the focus on input element in angular js

I create one input element and on click show the list of items after selecting any item list get hide.
But the focus is not on that element it get down,
So I just want to manually set the focus on input element when radio button list get hide.
Here is use the following code,
View
<label class="item item-input item-stacked-label" ng-click="showDays()">
<span class="input-label black-text">DAYS</span>
<span class="input-ctrl">
<input type="text" id="days" readonly ng-model="data_day" focus-on="!daysflag">
</span>
</label>
<div ng-show="daysflag">
<ion-radio icon="ion-ios-checkmark" ng-model="data_day" ng-value="{{day}}" ng-repeat="day in days" ng-click="hideDayFlag()">{{day}}</ion-radio>
</div>
Controller
$scope.days = [1, 2, 3, 4, 5, 6, 7];
$scope.showDays = function() {
$scope.daysflag = true;
}
$scope.hideDayFlag = function() {
$scope.daysflag = false;
}
Directive
.directive('focusOn',function($timeout) {
return {
restrict : 'A',
link : function($scope,$element,$attr) {
$scope.$watch($attr.focusOn,function(_focusVal) {
$timeout(function() {
_focusVal ? $element[0].focus() :
$element[0].blur();
});
});
}
}
});
Please help me to solve this issue.
You are wrong to use the function scope.$watch. scope.$watch is used to track changes in the $scope.
See detail explanation.
Example on jsfiddle.
angular.module('ExampleApp', [])
.controller('ExampleController', function() {
var vm = this;
vm.isFocus = false;
})
.directive('focusOn', function() {
return {
restrict: 'A',
scope: {
focusOn: "="
},
link: function(scope, $element, $attr) {
scope.$watch('focusOn', function(_focusVal) {
_focusVal ? $element[0].focus() :
$element[0].blur();
});
$element.on("focus", function() {
scope.$applyAsync(function() {
scope.focusOn = true;
});
});
$element.on("blur", function() {
scope.$applyAsync(function() {
scope.focusOn = false;
});
})
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="ExampleController as vm">
<input ng-model="vm.countRow" focus-on="vm.isFocus">
<input type="button" value="Focus" ng-click="vm.isFocus=true">
<input type="button" value="Blur" ng-click="vm.isFocus=false">{{vm.isFocus}}
</div>
</div>

How can I auto check elements in nested ng-repeat?

I have a div which contains ng-repeat elements. These ng-repeat elements are inter-related to each other. Elements of ng-repeat are having checkboxes. What I want is when the element of top ng-repeat is check it should auto check the elements in other ng-repeat. Below picture is showing the actual representation of elements and next pic is showing what actually I am trying to achieve.
I did try this but it is not working at all
<div actor-check-box ng-repeat="actor in actors">
<div create-connections class="actor\{{$index}}" >
<span><input class="checkbox-actor" type="checkbox" name="actor-checkbox" id="actor-checkbox\{{$index}}">\{{actor}}</span>
</div>
<div ng-repeat="activity in activities">
<div ng-if="actor == activity.id">
<div ng-repeat = "impact in activity.text" >
<div update-connections class="impact\{{$index}}actor\{{actors.indexOf(actor)}}" actor-id="actor\{{actors.indexOf(actor)}}">
<span><input class="checkbox-activity" type="checkbox" name="impact-checkbox" id="activity-checkbox\{{$index}}actor\{{actors.indexOf(actor)}}" activity-check-box>\{{impact}}</span>
</div>
<div ng-repeat="feature in features">
<div ng-if="actor == feature.id && impact == feature.key">
<div feature-connection ng-repeat = "feature in feature.text" class="feature\{{$index}}" activity-id="impact\{{activity.text.indexOf(impact)}}actor\{{actors.indexOf(actor)}}" id="">
<span><input class="checkbox" type="checkbox" name="impact-checkbox" id="" >\{{feature}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Directive code:
angular.module('mainModule').directive('activityCheckBox', function($interval) {
return {
restrict: 'EA',
/*replace: false,*/
scope: {
ngModel:'='
}
/*require: 'createConnections','updateConnections', 'featureConnection'*/,
/*transclude: true,*/
link: function(scope, element, attrs) {
element.find('input[type="checkbox"]').prop('checked',true);
}
};
});
angular.module('mainModule').directive('actorCheckBox', function($interval) {
return {
restrict: 'EA',
/*transclude: true,*/
link: function (scope, element, attrs, ctrl) {
console.log(element);
scope.$watch('ngModel', function(newValue){
element.find('input[type="checkbox"]').prop('activityCheckBox',true).trigger('change');
});
}
}
});
This cannot be implemented using the normal way we follow to check and uncheck elements. I used emit and brodcast inside the directive by capturing the dom. Here is the code I wrote and it works like a charm:
angular.module('mainModule').directive('allCheckboxesBroadcast', function($interval) {
return {
restrict: 'A',
controller: function($scope) {
$scope.checkAll = function (model,id) {
if (model == true){
$scope.$broadcast('allCheckboxes',id, true);
}else{
$scope.$broadcast('allCheckboxes',id, false);
}
}
}
};
});
angular.module('mainModule').directive('allCheckboxesListeners', function($interval) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
attrs.$observe('actorId', function(value) {
scope.$on('allCheckboxes', function(event, id,shouldCheckAllCheckboxes) {
actorId = 'actor' + id;
if (value == actorId){
element.find('input').prop('checked', shouldCheckAllCheckboxes);
$scope.$broadcast('featureCheckboxesListeners', actorId, true);
}
});
});
}
};
});

Categories

Resources