AngularJS show/hide with a function() call - angularjs

Is it possible to show/hide an element after a function call that returns a boolean? Scenario is, to show "Ready" when all n-items have an "agreed" flag. If not, show something else. Value of agreed flag is changed with a radio button.
$scope.data = [
{
title: "Agreement #1",
agreed: false,
},
{
title: "Agreement #2",
agreed: false,
},
];
$scope.ready = function()
{
var go = true;
angular.forEach($scope.data, function(item, key) {
go &= item.agreed==true;
});
return go;
}
Then, calling:
<div ng-show="ready()">Go!</div>
<div ng-hide="ready()">Missing the points.</div>
Problem with this code: If all radio buttons are checked, ie. all values of agreed flag are set to true, the ready() is not auto updated.

You can bind the boolean value of agreed to the ng-model of the radio button and use ng-value for setting true/false for each agreement.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.data = [
{
title: "Agreement #1",
agreed: false,
},
{
title: "Agreement #2",
agreed: false,
}
]
$scope.ready = function()
{
var go = true;
angular.forEach($scope.data, function(item, key) {
go &= item.agreed==true;
});
return go;
}
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-show="ready()">Go!</div>
<div ng-show="!ready()">Missing the points.</div>
<table>
<tr>
<th>Agreement </th>
<th>Status</th>
</tr>
<tr ng-repeat="value in data">
<td>{{value.title}}</td>
<td>
Yes <input type="radio" ng-model="value.agreed" ng-value="true" />
No <input type="radio" ng-model="value.agreed" ng-value="false" />
</td>
</tr>
</table>
<span>{{data}}</span>
</div>
</body>
</html>

i think u missed the data variable square bracket
$scope.data = [
{
title: "Agreement #1",
agreed: true,
},
{
title: "Agreement #2",
agreed: false,
},
];
https://plnkr.co/edit/xWdro1SCUTeLbRVbEMWi?p=preview

Related

I was doing a functionality in Angular JS, When I search and click on button, related search data has to display using ng-click and ng-repeat

<script>
var app = angular.module("myApp", ['ngRoute']);
app.controller("myCtrl", function($scope) {
$scope.srch = [{
name: "Rani",
phno:"145365463"
},
{
name: "Raj",
phno:"989365463"
},
{
name: "Sai",
phno:"782144635"
},
{
name: "roja",
phno:"5365463889"
},
{
name: "Priya",
phno:"321565463"
}
]
</script>
<html>
<head>
<title>Sample</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-route.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div>
<input type="text" ng-model="search" placeholder="Search for name or email" style="width:200px;"></input>
<table class="table table-striped" ng-show="search">
<tr ng-repeat="y in srch | filter: search">
<td>{{y.name}}</td>
<td>{{y.phno}}</td>
</tr>
</table>
</div>
</body>
</html>
First point, input tag has no end tag.
Then, your AngularJS script is false. Controller code is never closed.
var app = angular.module("myApp", ['ngRoute']);
app.controller("myCtrl", function($scope) {
$scope.srch = [{
name: "Rani",
phno:"145365463"
},
{
name: "Raj",
phno:"989365463"
},
{
name: "Sai",
phno:"782144635"
},
{
name: "roja",
phno:"5365463889"
},
{
name: "Priya",
phno:"321565463"
}
];
}); // Don't forget to close
Avoid declaring ngApp and ngController on same element.
See this Plunkr working: https://plnkr.co/edit/n1lJ4uSdM5Nc7xZxM7XB?p=preview
You have to type some chars to make your list appear. What I can recommend to you is to filter your ngRepeat with a function instead of variable.

Why does the Ajax not updating the model correctly?

I am new to angularjs and is using code sample in book "pro-angularjs" to do some test run (it has an initial list of items, but then use Ajax to update list):
<!DOCTYPE html>
<html ng-app="todoApp">
<head>
<title>TO DO List</title>
<link href="bootstrap.css" rel="stylesheet" />
<link href="bootstrap-theme.css" rel="stylesheet" />
<script src="angular.js"></script>
<script>
var model = {
user: "Adam",
items: [{ action: "Buy Flowers", done: false },
{ action: "Get Shoes", done: false },
{ action: "Collect Tickets", done: true },
{ action: "Call Joe", done: false }],
};
var todoApp = angular.module("todoApp", []);
todoApp.run(function ($http) {
$http.get("todo.json").then(function successCallback(data) {
model.items = data;
});
});
todoApp.filter("checkedItems", function () {
return function (items, showComplete) {
var resultArr = [];
angular.forEach(items, function (item) {
if (item.done == false || showComplete == true) {
resultArr.push(item);
}
});
return resultArr;
}
});
todoApp.controller("ToDoCtrl", function ($scope) {
$scope.todo = model;
$scope.incompleteCount = function () {
var count = 0;
angular.forEach($scope.todo.items, function (item) {
if (!item.done) { count++ }
});
return count;
}
$scope.warningLevel = function () {
return $scope.incompleteCount() < 3 ? "label-success" : "label-warning";
}
$scope.addNewItem = function (actionText) {
$scope.todo.items.push({ action: actionText, done: false });
}
});
</script>
</head>
<body ng-controller="ToDoCtrl">
<div class="page-header">
<h1>
{{todo.user}}'s To Do List
<span class="label label-default" ng-class="warningLevel()"
ng-hide="incompleteCount() == 0">
{{incompleteCount()}}
</span>
</h1>
</div>
<div class="panel">
<div class="input-group">
<input class="form-control" ng-model="actionText" />
<span class="input-group-btn">
<button class="btn btn-default"
ng-click="addNewItem(actionText)">Add</button>
</span>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>Description</th>
<th>Done</th>
</tr>
</thead>
<tbody>
<tr ng-repeat=
"item in todo.items | checkedItems:showComplete | orderBy:'action'">
<td>{{item.action}}</td>
<td><input type="checkbox" ng-model="item.done" /></td>
</tr>
</tbody>
</table>
<div class="checkbox-inline">
<label><input type="checkbox" ng_model="showComplete"> Show Complete</label>
</div>
</div>
</body>
</html>
the only change i made was:
todoApp.run(function ($http) {
$http.get("todo.json").then(function successCallback(data) {
model.items = data;
});
});
it was initially:
$http.get("todo.json").success(function (data) {
model.items = data;
});
which does not run with the latetest version angularjs, and so i made the change.
when debugging, i found that the initial value of model.items is:
and it is correctly showing in UI (see left side of screenshot).
After the ajax, its value is updated to 'data' whose value is:
the value of data looks fine to me (same as initial value of items).
But after i let go the debugger, finally in UI all items are gone.
I do understand why? it seems 'items' is the same as 'data'. Anyone has a clue on how i can debug further to find out the root cause?
Thanks,
btw, the 'todo.json' i used is below:
[{ "action": "Buy Flowers", "done": false },
{ "action": "Get Shoes", "done": false },
{ "action": "Collect Tickets", "done": true },
{ "action": "Call Joe", "done": false }]
You are not updating your model correctly. As you can see from your screenshot, data contains an object data which should be assigned to your model.
todoApp.run(function ($http) {
$http.get("todo.json").then(function successCallback(data) {
model.items = data.data;
});
});

make JSON array from dynamic form data angular

i have a dynamic form in angular. and i want to send the response as json. how do i generate JSON from the form?
here's the complete code,I have to get json, and post it to some api.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="dyf" ng-submit="submit()">
<form name="userFormOne" novalidate>
<table>
<tr class="form-group" ng-repeat="x in names">
<td><label>{{ x.Field }}</label>
</td><td><input type="text" class="form-control" placeholder="{{x.Comment}}" required>
</td>
</tr>
</table>{{data}}
</form>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('dyf', function($scope, $http) {
$http.get("http://localhost:5000/gu")
.then(function (response) {$scope.names = response.data;console.log(response.data);});
$scope.data ={};
});
</script>
</body>
</html>
In AngularJs we use ng-model to bind inputs value to our controller, sample:
This full sample to figure out how to create a simple form, from array and how to send it as JSON to your API.
Note: On submit check your console, and see the objects value.
var app = angular.module("app", []);
app.controller("ctrl",
function ($scope) {
var options = [
{ name: "a" },
{ name: "b" },
{ name: "c" }
];
$scope.names = [
{ id: 1, field: "insert name", name: "name", placeholder: "your name is", value:null, type:"text" },
{ id: 2, field: "insert phone", name: "phone", placeholder: "your phone is", value: null, type: "tel" },
{ id: 3, field: "insert age", name: "age", placeholder: "your age is", value: null, type: "number", min: 0, max: 20 },
{ id: 4, field: "select country", name: "country", placeholder: "your country is", value: null, type: "select", options: options }
];
$scope.sendMe = function() {
console.log($scope.names);
}
});
<!DOCTYPE html>
<html ng-app="app" ng-controller="ctrl">
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<form name="userFormOne" novalidate>
<table>
<tr class="form-group" ng-repeat="x in names">
<td>
<label>{{ x.field }}</label>
</td>
<td ng-if="x.type != 'select'">
<input type="{{x.type}}" min="{{x.min}}" max="{{x.max}}" ng-model="x.value" name="{{x.name}}" placeholder="{{x.placeholder}}" ng-required="true">
{{x.value}}
</td>
<td ng-if="x.type == 'select'">
<select ng-model="x.value" name="{{x.name}}" ng-options="item as item.name for item in x.options">
</select>
{{x.value}}
</td>
</tr>
</table>
<button ng-disabled="userFormOne.$invalid" ng-click="sendMe()">sendMe</button>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</body>
</html>

Angular js - Multiple input per row edit & save

<div ng-controller="MyController">
<table border="1">
<tr data-ng-repeat="item in items">
<td data-ng-repeat="textValue in item.value">
<input type="text" data-ng-model="textValue" data-ng-readonly="isReadonly" />
</td>
</tr>
</table>
<input type="button" value="Edit" data-ng-click="enableEdit();" />
</div>
Will have multiple rows with multiple input type text for each row. Initially onload input type are set to readonly. Once user press the edit button all of the input box will become editable. User can change the text box values & save the updated values by clicking on save button.
var MyModule = angular.module('MyModule', []);
MyModule.controller("MyController", function($scope) {
$scope.isReadonly = true;
$scope.items = [{
"id": 1,
"value": {
"value1": 10,
"value2": 20,
"value3": 30,
"value4": 40
}
}, {
"id": 2,
"value": {
"value1": 50,
"value2": 60,
"value3": 70,
"value4": 80
}
}];
$scope.enableEdit = function() {
$scope.isReadonly = false;
}
});
Follow the below plnkr url
http://plnkr.co/edit/g0bpUg2AVjNhWAXG8PXc?p=preview
You should be using ng-if to toggle between the controls as below
<tr data-ng-repeat="item in items">
<td data-ng-repeat="textValue in item.value">
<label class="form-control" ng-if="isReadonly">{{textValue}} </label>
<input type="text" ng-if="!isReadonly" data-ng-model="textValue" />
</td>
</tr>
Controller Method
$scope.enableEdit = function() {
$scope.isReadonly = false;
}
$scope.saveValues=function(){
$scope.isReadonly = true;
}
LIVE DEMO(UPDATED PLUNK)
I assume the problem you are facing is related to changes not getting reflected back to the model.
The assumption was made because you haven't told us your problem in the first place.
Note: I've also added the saveValues() function for completeness.
The problem is due to how ngRepeat directive works and how you have used it. ng-repeat creates a child scope for each textValue and in these child scopes, ng-repeat does not create a 2-way binding for the textValue value. And so your model was never updated.
There are two different ways to solve this:
P.S: Example#2 is just for the demonstration of object technique and should be avoided for your use-case as it would further complicate the data structure of items.
Example#1) Using (key, value) like:
var MyModule = angular.module('MyModule', []);
MyModule.controller("MyController", function($scope) {
$scope.isReadonly = true;
$scope.items = [{
"id": 1,
"value": {
"value1": 10,
"value2": 20,
"value3": 30,
"value4": 40
}
}, {
"id": 2,
"value": {
"value1": 50,
"value2": 60,
"value3": 70,
"value4": 80
}
}];
$scope.enableEdit = function() {
$scope.isReadonly = false;
}
$scope.saveValues = function() {
$scope.isReadonly = true;
console.log($scope.items)
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="MyModule">
<div ng-controller="MyController">
<table border="1">
<tr data-ng-repeat="item in items">
<td data-ng-repeat="(key, textValue) in item.value">
<input type="text" data-ng-model="item.value[key]" data-ng-readonly="isReadonly" />
</td>
</tr>
</table>
<input type="button" value="Edit" data-ng-click="enableEdit();" />
<input type="button" value="Save" data-ng-click="saveValues();" />
</div>
Example#2) Using objects like:
var MyModule = angular.module('MyModule', []);
MyModule.controller("MyController", function($scope) {
$scope.isReadonly = true;
$scope.items = [{
"id": 1,
"value": {
"value1": {
"value": 10
},
"value2": {
"value": 20
},
"value3": {
"value": 30
},
"value4": {
"value": 40
}
}
}, {
"id": 2,
"value": {
"value1": {
"value": 50
},
"value2": {
"value": 60
},
"value3": {
"value": 70
},
"value4": {
"value": 80
}
}
}];
$scope.enableEdit = function() {
$scope.isReadonly = false;
}
$scope.saveValues = function() {
$scope.isReadonly = true;
console.log($scope.items)
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="MyModule">
<div ng-controller="MyController">
<table border="1">
<tr data-ng-repeat="item in items">
<td data-ng-repeat="textValue in item.value">
<input type="text" data-ng-model="textValue.value" data-ng-readonly="isReadonly" />
</td>
</tr>
</table>
<input type="button" value="Edit" data-ng-click="enableEdit();" />
<input type="button" value="Save" data-ng-click="saveValues();" />
</div>

AngularJS - dynamic rows and columns with a two way bound custom control

I am new to Angular and am stuck on my next step of development which is to have a custom control bound to a dynamic row-column table.
I have a simple fiddle here which shows how to data bind a custom control:
http://jsfiddle.net/paull3876/WPWAc/2/
And another fiddle here which is my starting point, shows how to bind a row-column table with data driven column names:
http://jsfiddle.net/paull3876/3mz5L/1/
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Angular</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.min.js"></script>
<script>
var app = angular.module("myApp", []);
function datacontroller($scope, $http)
{
$scope.mydata = [{f1:"r1f1", f2:"r1f2"}, {f1:"r2f1",f2:"r2f2"}, {f1:"r3f1",f2:"r3f2", f3:"Hello"}];
$scope.mycolumns = [{name:"Column 1", fieldname:"f1"}, {name:"Column 2", fieldname:"f2"}, {name:"Column 3", fieldname:"f3"}];
$scope.showdata = function()
{
alert(JSON.stringify($scope.mydata));
}
$scope.getcolumnname = function(cell)
{
return cell.fieldname;
}
}
</script>
</head>
<body>
<div data-ng-controller="datacontroller">
<table>
<tr>
<td data-ng-repeat="cell in mycolumns">{{cell.name}}</td>
</tr>
<tr data-ng-repeat="record in mydata">
<td data-ng-repeat="cell in mycolumns">
<input type="text" data-ng-init="mycol=getcolumnname(cell);" data-ng-model="record[mycol]" />
</td>
</tr>
</table>
<br />
<input type="button" value="Save Data" ng-click="showdata()" />
<br />
<br />
</div>
</body>
</html>
Now I want to take the second fiddle above, and replace the INPUT element with a user control which has two way data binding. I've spend a day on this already and can't get it working, so I guess I'm also needing some help on the concepts here
An explanation on top of a solution greatly appreciated.
http://jsfiddle.net/paull3876/rc7uC/1/
Here's the full working solution, I hope someone finds it useful.
<!DOCTYPE html>
<html >
<head>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="expires" content="-1">
<title>Angular</title>
<!--scr ipt src="htt ps://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.min.js"></script-->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js"></script>
</head>
<body>
<div data-ng-app="myApp" data-ng-controller="datacontroller">
<table>
<tr>
<td data-ng-repeat="cell in mycolumns">{{cell.name}}</td>
</tr>
<tr data-ng-repeat="record in mydata">
<td data-ng-repeat="cell in mycolumns">
<mycontrol data-my-model="record[cell.fieldname]"></mycontrol>
</td>
</tr>
</table>
<br />
<input type="button" value="Save Data" ng-click="showdata()" />
<input type="button" value="Change Divs" onclick="changediv()" />
<input type="button" value="Change Scope" onclick="changescope()" />
<br />
<br />
</div>
</body>
</html>
<script>
var globalscope;
var app = angular.module("myApp", [])
.directive("mycontrol", function ($compile) {
return {
restrict: "E",
scope: {
value: "=myModel"
},
template: "<div data-ng-bind='value'/>"
};
});
function datacontroller($scope, $http) {
globalscope = $scope;
var mydata = [];
// generate some data
for (var i = 0; i < 20; i++)
{
var row = {
f1:"f1x" + i,
f2:"f2x" + i,
f3:"f3x"+i,
f4:"f4x"+i,
f5:"f5x"+i,
f6:"f6x"+i,
f7:"f7x"+i,
f8:"f8x"+i,
f9:"f9x"+i,
f10:"f10x"+i,
f11:"f11x"+i,
f12:"f12x"+i,
f13:"f13x"+i
};
mydata.push(row);
}
// push it to angulars scope
$scope.mydata = mydata;
// generate some metadata for the columns
$scope.mycolumns = [{
name: "Column 1",
fieldname: "f1",
type: "input"
}, {
name: "Column 2",
fieldname: "f2",
type: "textarea"
}, {
name: "Column 3",
fieldname: "f3",
type: "div"
}, {
name: "Column 4",
fieldname: "f4",
type: "div"
}, {
name: "Column 5",
fieldname: "f5",
type: "div"
}, {
name: "Column 6",
fieldname: "f6",
type: "div"
}, {
name: "Column 7",
fieldname: "f7",
type: "div"
}, {
name: "Column 8",
fieldname: "f8",
type: "div"
}, {
name: "Column 9",
fieldname: "f9",
type: "div"
}, {
name: "Column 10",
fieldname: "f10",
type: "div"
}, {
name: "Column 11",
fieldname: "f11",
type: "div"
}, {
name: "Column 12",
fieldname: "f12",
type: "div"
}, {
name: "Column 13",
fieldname: "f13",
type: "div"
}];
$scope.showdata = function () {
alert(JSON.stringify($scope.mydata));
};
$scope.getcolumnname = function (cell) {
return cell.fieldname;
};
}
function changediv()
{
// this will change the data in the divs but it won't reflect back to the scope
var divs = document.getElementsByClassName("fred");
for (var i = 0; i < divs.length; i++)
{
var div = divs[i];
div.innerText = "XXXX";
}
}
function changescope()
{
// shows how to change data programmatically and have it reflected in the controls and in the scope data
var scope = globalscope;
for (r in scope.mydata)
{
scope.mydata[r].f3 = "UUUU";
}
scope.$apply();
}
</script>

Resources