ng-repeat values evaluated outside by ng-if - angularjs

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>

Related

When I click reset button or load this page, all the fields are empty

Output image:
I tried comparing the original code with this but I'm unable to find any mistakes. I'm very confused why this is not working. When page is reloaded or reset button is clicked all fields has to be filled with details but its not happening. What might be the mistake?
<html>
<head>
<title>Angular practice</title>
</head>
<body>
<div ng-app="" ng-controller="studentController">
<form name="studentForm" novalidate>
<table>
<tr>
<td>first name</td>
<td><input name="firstname" type="text" ng-model="firstName" required>
<span style="color: red;" ng-show="studentForm.firstname.$dirty && studentForm.firstname.$invalid">
<span ng-show="studentForm.firstname.$error.required">enter first name</span>
</span>
</td>
</tr>
<tr>
<td>last name</td>
<td><input name="lastname" type="text" ng-model="lastName" required>
<span style="color: red;" ng-show="studentForm.lastname.$dirty && studentForm.lastname.$invalid">
<span ng-show="studentForm.lastname.$error.required">enter last name</span>
</span>
</td>
</tr>
<tr>
<td>email</td>
<td><input name="email" type="email" ng-model="email" required>
<span style="color: red;" ng-show="studentForm.email.$dirty && studentForm.email.$invalid">
<span ng-show="studentForm.email.$error.required">enter email ID</span>
<span ng-show="studentForm.email.$error.email">Invalid email</span>
</span>
</td>
</tr>
<tr>
<td><button ng-click="reset()">Reset</button></td>
<td><button ng- disabled="studentForm.firstname.$dirty &&
studentForm.firstname.$invalid ||
studentForm.lastname.$dirty && studentForm.lastname.$invalid||
studentForm.email.$dirty && studentForm.email.$invalid"
ng-click="submit()">Submit</button>
</td>
</tr>
</table>
</form>
</div>
<script>
function studentController($scope){
$scope.reset = function(){
$scope.firstName = "uthej";
$scope.lastName = "ks";
$scope.email = "uthej#gmail.com";
}
$scope.reset();
}
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
</body>
</html>
ng-app is missing in your HTML code and you are not injecting controller in app.
HTML Code
<div ng-app="myApp" ng-controller="studentController">
Js code
var app = angular.module('myApp', []);
app.controller('studentController', function ($scope) {
$scope.reset = function () {
$scope.firstName = "uthej";
$scope.lastName = "ks";
$scope.email = "uthej#gmail.com";
}
$scope.reset();
});
you have misspelled HTML & Script, Correct one is..
Html::
<div ng-app="demoApp" ng-controller="studentController">
<form name="studentForm" novalidate>
// form fields will goes here....
</form>
</div>
& script::
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script>
var app = angular.module("demoApp", []);
app.controller("studentController", function($scope){
$scope.reset = function(){
$scope.firstName = "uthej";
$scope.lastName = "ks";
$scope.email = "uthej#gmail.com";
};$scope.reset();
});
</script>
I hope it will work for you.

Get all dirty form fields by table row in AngularJS

I have a form that is rendered inside of an HTML table using AngularJS, similar to:
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<form name="inputData" id="inputData" ng-submit="submit()">
<table class="table">
<tr>
<th>Name</th>
<th>Employees</th>
<th>Head Office</th>
</tr>
<tr ng-repeat="company in companies">
<td>
<input type="text" ng-model="company.name" />
</td>
<td>
<input type="text" ng-model="company.employees" />
</td>
<td>
<input type="text" ng-model="company.headoffice" />
</td>
</tr>
</table>
<input type="submit"/>
</form>
</div>
</div>
Users can edit the values in the form. When the form is submitted, I'd like to get the $index of the row(s) that were edited. That way I can access the full row from the model via $scope.companies[$index] (which is going to get POSTed to a server).
I know I can check individual fields for the $dirty property. But is there a way I can retrieve the row number? Or better yet, a way I can retrieve all fields in the edited rows?
Here's a fiddle where, right now, I'm just highlighting the dirty fields using CSS: https://jsfiddle.net/jmg157/kzxeL0yw/2/
Thanks for any and all help!
You can try something like this ( using angular.equals) :
var app = angular.module("myApp", []);
app.controller("MyCtrl", ["$scope", function($scope) {
$scope.companies = [{
name: "Infosys Technologies",
employees: 125000,
headoffice: "Bangalore"
}, {
name: "Cognizant Technologies",
employees: 100000,
headoffice: "Bangalore"
}, {
name: "Wipro",
employees: 115000,
headoffice: "Bangalore"
}];
$scope.orginalCompanies = angular.copy($scope.companies);
$scope.submit = function() {
$scope.changedIndex = [];
if(angular.equals($scope.orginalCompanies, $scope.companies)){
console.log('NOthing is changed');
}else{
angular.forEach($scope.companies, function(value, key) {
if(!angular.equals(value, $scope.orginalCompanies[key])){
$scope.changedIndex.push(key);
}
});
console.log("changed Index:=>");
console.log($scope.changedIndex);
}
}
}]);
input.ng-dirty {
background-color: #ff0000;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<form name="inputData" id="inputData" ng-submit="submit()">
<table class="table">
<tr>
<th>Name
</th>
<th>Employees
</th>
<th>Head Office
</th>
</tr>
<tr ng-repeat="company in companies">
<td>
<input type="text" ng-model="company.name" />
</td>
<td>
<input type="text" ng-model="company.employees" />
</td>
<td>
<input type="text" ng-model="company.headoffice" />
</td>
</tr>
</table>
<input type="submit"/>
</form>
</div>
</div>
You can simply use ng-change directive:
angular.module("myApp", []).controller("MyCtrl", ["$scope", function($scope) {
$scope.companies = [{
name: "Infosys Technologies",
employees: 125000,
headoffice: "Bangalore"
}, {
name: "Cognizant Technologies",
employees: 100000,
headoffice: "Bangalore"
}, {
name: "Wipro",
employees: 115000,
headoffice: "Bangalore"
}];
$scope.submit = function() {
console.log($scope.inputData);
}
$scope.logs = [];
$scope.logDirty = function(key, $index) {
var message = 'company[' + $index + '].' + key + 'is dirty';
if ($scope.logs.indexOf(message) == -1)
$scope.logs.push(message);
}
}]);
input.ng-dirty {
background-color: #ff0000;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<form name="inputData" id="inputData" ng-submit="submit()">
<table class="table">
<tr>
<th>Name
</th>
<th>Employees
</th>
<th>Head Office
</th>
</tr>
<tr ng-repeat="company in companies" ng-init='parentIndex=$index'>
<td ng-repeat='(key, val) in company'>
<input ng-change='logDirty(key, parentIndex)' type="text" ng-model="company[key]" />
</td>
</tr>
</table>
<input type="submit" />
<ul ng-if='logs.length > 0'>
<li ng-repeat='log in logs'>{{log}}</li>
</ul>
</form>
</div>
</div>

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

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

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

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