ng-change does not trigger when the checkbox is already checked - angularjs

Here is the background:the checkbox was checked when "isChecked == 1" while its initalization,however,it doesn't trigger the "ng-change" event in its first "click" action.
<td ng-repeat="isCheck in item.check track by $index">
<input type="checkbox" ng-model="isCheck" ng-checked="isCheck == 1" ng-true-value="1" ng-false-value="0" ng-change="f(isCheck, item, vm.modules[$index])"/>
</td>

Check this working code:
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function ($scope) {
$scope.item = {};
$scope.item.check = [1, 0, 1, 0];
$scope.f = function(isCheck) {
console.log(isCheck);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<table>
<tr>
<td ng-repeat="isCheck in item.check track by $index">
<input type="checkbox" ng-model="isCheck" ng-checked="isCheck === 1" ng-true-value="1" ng-false-value="0" ng-change="f(isCheck)"/>
</td>
</tr>
</table>
</div>
</div>

ng-checked cannot work alongside ng-change if ng-model is changed programatically, check official docs:
https://docs.angularjs.org/api/ng/directive/ngChange

Related

angularjs checkbox with ng-repeat

i want to make something like this
angularjs-checkbox
this is my code
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head></head>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.records = [
"ALL",
"KOREAN",
"ENGLISH",
"CHINESE",
"JAPANESE",
"GERMAN",
"FRENCH",
"ITALIAN",
"SPANISH",
"OTHERS",
]
});
</script>
<body class="other_page" ng-app="myApp">
<table class="checkbox_table" ng-controller="myCtrl">
<tr>
<td colspan="3" class="filter_subtitle_td">
<div class="filter_subtitle">
<span>
CATEGORY
</span>
</div>
</td>
</tr>
<tr ng-repeat="x in records" ng-if="$index % 3 == 0">
<td class="checkbox_td">
<input type="checkbox" id="{{records[$index]}}" class="category_filter_checkbox" ng-model="all" />
<label for="{{records[$index]}}" class="checkbox_label">
{{records[$index]}}
</label>
</td>
<td class="checkbox_td" ng-if="x != ''">
<input type="checkbox" id="{{records[$index + 1]}}" class="category_filter_checkbox" ng-checked="all" />
<label for="{{records[$index + 1]}}" class="checkbox_label">
{{records[$index + 1]}}
</label>
</td>
<td class="checkbox_td" ng-if="x != ''">
<input type="checkbox" id="{{records[$index + 2]}}" class="category_filter_checkbox" ng-checked="all" />
<label for="{{records[$index + 2]}}" class="checkbox_label">
{{records[$index + 2]}}
</label>
</td>
</tr>
</table>
</body>
</html>
my questions is:
how to make ng-repeat stop when no data left?
how to give only 'ALL' data ng-model so the other checkbox can be selected by click this 'ALL' checkbox?
Thank you for your help
I think you chose too complicated way.
To simplify you can use lodash.com or underscorejs and split array to chunks as: $scope.records = _.chunk(data, 3);
So output will be:
[[{"type":"ALL","value":false},{"type":"KOREAN","value":false},{"type":"ENGLISH","value":false}],[{"type":"CHINESE","value":false},{"type":"JAPANESE","value":false},{"type":"GERMAN","value":false}],[{"type":"FRENCH","value":false},{"type":"ITALIAN","value":false},{"type":"SPANISH","value":false}],[{"type":"OTHERS","value":false}]]
Further, to make checkboses to work properly with ng-model we need pass not primitive but objects as {type:<NAME>, value:true/false}:
var data = [
{type:"ALL",value:false},
{type:"KOREAN",value:false},
{type: "ENGLISH",value:false},
{type: "CHINESE",value:false},
{type:"JAPANESE",value:false},
{type: "GERMAN",value:false},
{type:"FRENCH",value:false},
{type:"ITALIAN",value:false},
{type:"SPANISH",value:false},
{type:"OTHERS",value:false}
];
$scope.all = angular.copy(data[0]);
$scope.records = _.chunk(data, 3);
So your HTML will look like:
<table class="checkbox_table" ng-controller="myCtrl">
<tr>
<td colspan="3" class="filter_subtitle_td">
<div class="filter_subtitle">
<span>
CATEGORY
</span>
</div>
</td>
</tr>
<tr ng-repeat="record in records" >
<td ng-repeat="x in record" >
<input type="checkbox" ng-model="all.value" ng-if="x.type === 'ALL'" />
<input type="checkbox" ng-model="x.value" ng-checked="all.value" ng-if="x.type !== 'ALL'" />
<label for="{{x.type}}" ng-if="x.type !== 'ALL'" >{{x.type}}</label>
<label for="{{all.type}}" ng-if="x.type === 'ALL'" >{{x.type}}</label>
</td>
</tr>
</table>
Demo Fiddle

AngularJS How to place focus on textbox when button click

i have one textbox and few buttons and i want when user will click on any button then textbox will have focus. i tried this way but did not work angular.element("#txtData").focus();
my full code
<div ng-app="myApp" ng-controller="myCtrl">
<table border=2>
<tr>
<td colspan=5><input type=text ng-model="Operantion" id="txtData" style="width:97%" ng-change="GetData(Operantion,'onChange')"></td>
</tr>
<tr>
<td><input type=button value="+" ng-click="GetData('+','btnClick')"></td>
<td><input type=button value="-" ng-click="GetData('-','btnClick')"></td>
<td><input type=button value="x" ng-click="GetData('*','btnClick')"></td>
<td><input type=button value="/" ng-click="GetData('/','btnClick')"></td>
<td><input type=button value="=" ng-click="GetData('=','btnClick')"></td>
</tr>
</table>
</div>
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.GetData = function (arg1, evtType) {
if (evtType === 'btnClick') {
angular.element("#txtData").focus();
}
};
});
js fiddle https://jsfiddle.net/tridip/wzvq5ov8/
i found few same kind of post in this forum and saw people write many code to achieve this by custom directives. i am so new and that is why i do not understand their code. one similar post url here which i checked https://stackoverflow.com/a/15529412/728750
this code angular.element("#txtData").focus(); suppose to work in angular but did not.......do i need to refer any library called jqLite ?
i heard jqLite is inbuilt in angular js...is it true. can anyone tell me why the this code did not function angular.element("#txtData").focus(); from controller function ?
i find out how to place focus with angular directives. here is code
jsfiddle https://jsfiddle.net/tridip/muz887hu/1/
<div class="main" ng-app="myApp">
<p>Name: <input type="text" ng-model="name" id="question1"></p>
<button id='btn' set-focus='question1'>click</button>
</div>
var myApp = angular.module('myApp',[]);
myApp.directive('setFocus',function(){
return {
link: function(scope, element, attrs){
element.bind('click',function(){
//alert(element.attr('id'));
document.querySelector('#' + attrs.setFocus).focus();
})
}
}
})
First of all, you have an eloquent error in your JS console that can lead you on the right way :
VM363 angular.js:12520 Error: [jqLite:nosel] Looking up elements via
selectors is not supported by jqLite! See:
http://docs.angularjs.org/api/angular.element
http://errors.angularjs.org/1.4.8/jqLite/nosel
So, don't use jqLite or jQuery, and use .focus() on the element itself, as simple as possible :
document.querySelector("#txtData").focus();
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.GetData = function(arg1, evtType) {
if (evtType === 'btnClick') {
document.querySelector("#txtData").focus();
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<table border=2>
<tr>
<td colspan=5>
<input type=text ng-model="Operantion" id="txtData" style="width:97%" ng-change="GetData(Operantion,'onChange')">
</td>
</tr>
<tr>
<td>
<input type=button value="+" ng-click="GetData('+','btnClick')">
</td>
<td>
<input type=button value="-" ng-click="GetData('-','btnClick')">
</td>
<td>
<input type=button value="x" ng-click="GetData('*','btnClick')">
</td>
<td>
<input type=button value="/" ng-click="GetData('/','btnClick')">
</td>
<td>
<input type=button value="=" ng-click="GetData('=','btnClick')">
</td>
</tr>
</table>
</div>

ng-repeat values evaluated outside by ng-if

How do you access ng-repeat data for conditional settings outside the ng-repeat directive scope? For instance, I would like to show a div block outside ng-repeat when someone selects a radio button generated within ng-repeat.
app.js
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.obj = [{
condition: "Question1",
status: "no"
}, {
condition: "Question2",
status: "no"
}];
}
.html
<tr ng-repeat="o in obj">
<td>{{o.condition}}</td>
<td>
Yes
<input type="radio" ng-model="o.status" value="yes" /> No
<input type="radio" ng-model="o.status" value="no" />
</td>
</tr>
<!-- this will show based on an input event-->
<div ng-if="o.status == 'yes'" class="myClass">
I show up
</div>
http://jsfiddle.net/fergnab/jmb619qg/
It is not possible. But you can try something like this.
add function that will check if obj have question with "ok" status
html
<div ng-if="someQuestionIsOk()" class="myClass">
controller
$scope.someQuestionIsOk = function someQuestionIsOk() {
for(var i = 0; i < $scope.obj.length; i++) {
if($scope.obj[i].status == 'yes')
return true;
}
return false;
}
EDIT
here is fiddle
EDIT
yet another possible solution is to use ng-change.
html
<input type="radio" ng-model="o.status" ng-change="statusChange(o)" value="yes" />
controller
$scope.answerIsYes = false;
$scope.statusChange = function statusChange(object) {
if(object.status == 'yes')
$scope.answerIsYes = true;
else
$scope.answerIsYes = $scope.someQuestionIsOk();
}
What I have here works locally, but not when I try it in js fiddle - I'm not sure why.
app.js (this is how I'm used to defining controllers):
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
$scope.obj = [{
condition: "Question0",
status: "no"
}, {
condition: "Question1",
status: "no"
}];
});
index.html (make a separate h1 for each o in obj):
<body ng-app="myApp">
<div ng-controller="MyCtrl">
<table>
<thead>
<th>Question</th>
<th>Status</th>
</thead>
<tbody>
<tr ng-repeat="o in obj">
<td>{{o.condition}}</td>
<td>
Yes <input type="radio" ng-model="o.status" value="yes" />
No <input type="radio" ng-model="o.status" value="no" />
</td>
</tr>
</tbody>
</table>
<!-- this will display "question 0" and/or "question 1", based on input -->
<div ng-repeat="o in obj">
<h1 ng-if="obj[$index].status === 'yes'" class="myClass">
question {{$index}}
</h1>
</div>
</div>
<script src="app.js"></script>
</body>

Set dropdown based on $scope match

I have a table that displays two columns using ng-repeat.
First column is a list of items pulled from one source.
Second column is a select element pulled from a second list.
What I want to do is automatically select an option in the dropdown, if it matches what is displayed in the left column.
I put together a fiddle: https://jsfiddle.net/raz1j9rt/1/
Here is my HTML:
<header>
<title>myTittle</title>
</header>
<body ng-app='myApp' ng-controller='myController'>
<div class="col-md-10 col-md-offset-1">
<div>
<form>
<table class="table table-striped">
<thead>
<th>From File</th>
<th>Map To</th>
</thead>
<tr class="selector-row" ng-repeat="(key,value) in List1">
<td><span id="myspan">{{value}}</span>
</td>
<td style="padding:10px;">
<select name="repeatSelect" id="repeatSelect" ng-model="data[value]" class="form-control">
<option ng-repeat="(key,value) in Match" value="{{value}}">{{value}}</option>
</select>
</td>
</tr>
</table>
</form>{{ data }}</div>
</div>
</body>
Here is my JS:
var app = angular.module('myApp', [])
app.controller('myController', ['$scope', function ($scope) {
$scope.data = {};
$scope.List1 = ['product1', 'product2', 'product3', 'product4', 'product5'];
$scope.Match = ['product1', 'somethtingElse1', 'product3', 'somethingElse2', 'product5'];
}])
Not really sure where to start on this...
Expanding on Claies point, here's a working fiddle.
https://jsfiddle.net/dboskovic/raz1j9rt/2/
Add this to your controller.
// setup default matches
angular.forEach($scope.List1, function(v){
$scope.data[v] = $scope.Match.filter(function(d){
if(d === v) return true;
return false;
})[0];
})
And then change your select to:
<select name="repeatSelect" id="repeatSelect" ng-model="data[value]" class="form-control" ng-options="x for x in Match"></select>

How to add the object values into table using angularjs

var app = angular.module("myapp", ["ngSanitize"]);
app.controller("controller", ['$scope', function($scope) {
$scope.tasks = [{
item: "Shopping",
status: true
}, {
item: "Cleaning",
status: false
}];
}]);
and html
<div ng-app="myapp">
<div ng-controller='controller'>
<table border=1 ng-repeat='task in tasks'>
<tr>
<td>{{task.item}}</td>
<td>{{task.status}}</td>
</tr>
</table>
</div>
</div>
I tried as above but i could not able to attach header to the table.And at the place of Done I am tring to attach a checkbox...I mean if status is true the chexk box must be checked or else unchecked.
Output:
Item Done
Shopping checkbox with ticked
Cleaning checkbox without ticked
See documentation for checkbox input
Not exactly the answer, but why do you repeat table instead of rows?
<div ng-app="myapp">
<div ng-controller='controller'>
<table border=1 >
<tr>
<th>Name</th>
<th>Status</th>
</tr>
<tr ng-repeat='task in tasks'>
<td>{{task.item}}</td>
<td><input type="checkbox" ng-model="task.status"></td>
</tr>
</table>
</div>
</div>
But I don't see any sense in table in your case.
<span ng-repeat="task in tasks">
<input type="checkbox" ng-model="task.status"> {{task.item}}
</span>
That would be much cleaner.
Do changes as follows in the HTML.
<body ng-app="myapp" ng-controller="ListController">
<table border="1" ng-repeat='task in tasks'>
<tr>
<td>
{{task.item}}
</td>
<td>
<input type="checkbox" ng-model="task.status">
</td>
</tr>
</table>
</body>
Do changes in the Angular js as follows.
var app = angular.module("myapp", []);
app.controller("ListController", ['$scope', function($scope) {
$scope.tasks = [{
item: "Shopping",
status: true
}, {
item: "Cleaning",
status: false
}];
}]);

Resources