Simple app doesn't bind to scope - javascript

I wrote a simple first app in AngularJS starting from a template for a todo list. None of the functions defined binds the scope (Both adding a new task or edit the current once). Anything I am doing commonly wrong in all the scopes of the controller?
Thanks in advance.
Here is my HTML:
<!DOCTYPE html>
<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0-beta.8/angular.js"></script>
<script src="js/script.js"></script>
<link href='//fonts.googleapis.com/css?family=Roboto:100,300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/style.css" />
</head>
<body>
<div class="page-container">
<h2>Todo</h2>
<ul class="todo-list" ng-repeat="todo in todos track by $index">
<li>
<span>{{ todo }}</span>
<button class="bt bt-achieve" ng-click="done(todo)">Done</button>
</li>
</ul>
</div>
<ul class="add-todo">
<li>
<input type="text" class="txt" placeholder="New Todo" ng-model="newTodo" ng-keyup="add($event)" />
</li>
</ul>
</body>
</html>
And my JS Script:
var app = angular.module('Todo', []);
app.controller('TodoCtrl', function($scope) {
$scope.newTodo = '';
$scope.todos = [
'Maged Task',
'Essam Task',
'Ashraf Task'
];
$scope.done = function(todo) {
var indexOf = $scope.todos.indexOf(todo);
if (indexOf !== -1) {
$scope.todos.splice(indexOf, 1);
}
};
$scope.add = function(e) {
if (e.which && e.which === 13) {
$scope.todos.push($scope.newTodo);
$scope.newTodo = '';
}
};
});

you haven't bound to the angular app or controller.
Try
<body ng-app="ToDo" ng-controller="TodoCtrl">

Change the body tag as below
<body ng-app="Todo" ng-controller="TodoCtrl" >
I always prefer to give initial data in ng-init method .
In your code you can use the initial data for $scope.todos like as below.
html code :
<body ng-app="Todo" ng-controller="TodoCtrl" ng-init="initialData()" >
javascript code
Inside controller
$scope.initialData = function(){
$scope.newTodo = '';
$scope.todos = [
'Maged Task',
'Essam Task',
'Ashraf Task'
];
}

change <body> to <body ng-app="Todo" ng-controller=TodoCtrl>

Related

How to implement "all check" button on AngularJS

I'm creating a button to check all checkboxes. The problem is that my "all check" button doesn't work to check off all checkboxes when I click the button.
How can I do this?
angular.module('myapp', [])
.controller('MainController', ['$scope', function($scope) {
$scope.allcheck = function(){
angular.forEach($scope.checkboxes, function(item){
item.selected = event.target.checked;
});
};
}]);
<!DOCTYPE html>
<html lang="en" ng-app="myapp">
<head>
<meta charset="UTF-8">
<title>AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="myscript.js"></script>
</head>
<body>
<h1>AngularJS</h1>
<div ng-controller="MainController">
<button ng-click="allcheck()">all check</button>
<input type="checkbox">a
<input type="checkbox">b
<input type="checkbox">c
</div>
</body>
</html>
When you start with Angular you should think and do in angular.
First you define your model:
$scope.selected = [false, false, false];
Then you render your model into view, using repeat. (I don't remember the syntax)
<div ng-repeat="item in selected">
<input type="checkbox" ng-model="item" />
</div>
Then you implement check all by just simply changing the model.
$scope.checkAll = function() {
for (var i = 0; i < $scope.selected.length; i++) {
$scope.selected[i] = true;
}
}
Don't think like you are working with JQuery, think like MVC.

angularjs hide/show add button after saving/create

I want to hide "add new button" when Im creating the record. and only show it back when Im done creating record.
Same as the "submit one button", I want to hide it (submit one button) and showing back the "add new button" as Im done submitting. How to do that?
below is my code and here is my plunkr:
index.html
<!DOCTYPE html>
<html ng-app="angularjs-starter">
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<link rel="stylesheet" href="style.css">
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<a ng-show="hideAddButton" ng-hide="hideAddButton" ng-click="addNew();hideAddButton = !hideAddButton">+ add new</a>
<form name="mainForm" ng-submit="submitAll()">
<ul>
<li ng-repeat="item in items" ng-form="subForm">
<input type="text" required name="name" ng-model="item.name"/>
<span ng-show="subForm.name.$error.required">required</span>
<button type="button" ng-disabled="subForm.$invalid" ng-click="submitOne(item);hideAddButton = !hideAddButton">Submit One</button>
</li>
</ul>
<button type="submit" ng-disabled="mainForm.$invalid">Submit All</button>
</form>
<hr/>
<div ng-show="lastSubmit">Last Submit:</div>
<pre>{{lastSubmit | json}}</pre>
</body>
</html>
app.js
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope) {
$scope.items = [];
$scope.addNew = function (){
$scope.items.push({ name: '' });
};
$scope.submitOne = function (item){
$scope.lastSubmit = angular.copy(item);
};
$scope.submitAll = function() {
$scope.lastSubmit = angular.copy($scope.items);
}
});
Here is my solution: http://plnkr.co/edit/8kOmWQ96UFkNOxZqcFMS?p=preview
app.controller('MainCtrl', function($scope) {
$scope.items = [];
$scope.isSubmitting = false;
$scope.addNew = function (){
$scope.isSubmitting = true;
// Here I added a state for each item.
$scope.items.push({ name: '', showButton:true });
};
$scope.submitOne = function (item){
item.showButton = false;
$scope.isSubmitting = false;
$scope.lastSubmit = angular.copy(item);
};
$scope.submitAll = function() {
$scope.items.forEach(function(i){i.showButton=false;})
$scope.isSubmitting = false;
$scope.lastSubmit = angular.copy($scope.items);
}
});
HTML
<body ng-controller="MainCtrl">
<a ng-hide="isSubmitting" ng-click="addNew();">+ add new</a>
<form name="mainForm" ng-submit="submitAll()">
<ul>
<li ng-repeat="item in items" ng-form="subForm">
<input type="text" required name="name" ng-model="item.name"/>
<span ng-show="subForm.name.$error.required">required</span>
<button ng-show="item.showButton" type="button" ng-disabled="subForm.$invalid" ng-click="submitOne(item);">Submit One</button>
</li>
</ul>
<button type="submit" ng-disabled="mainForm.$invalid">Submit All</button>
</form>
<hr/>
<div ng-show="lastSubmit">Last Submit:</div>
<pre>{{lastSubmit | json}}</pre>
</body>
I think this is what you are asking for, but I don't think the "submit all" button makes much sense in this scenario, unless you allow to add more items before submitting them (but you clearly state you want the "add new"-button hidden).
Also I was unsure if you actually wanted to store a state for each item, but showing/hiding all buttons didn't make much sense to me either...
You should use the ng-show or ng-hide directives.
with ng-show:
<button ng-show="hideAddButton === false">
with ng-hide:
<button ng-hide="hideAddButton === true">

The controller function is not being called

i'm learning AngularJs and i complete some courses in internet i know what is module, controller, service, i know some basics directives, and i found in internet a basic AngularJs video tutorial, i'm doing all like in this video but can't understand why it's not work.
Here is my code
var app = angular.module('todoApp', []);
app.controller('todoCtrl', ['$scope', function($scope) {
$scope.todos = [
{
text: "Learn AngularJs"
},
{
text: "Build App"
}
];
$scope.addTodo = function() {
$scope.todos.push({text: $scope.todoText});
};
}]);
<html ng-app="todoApp">
<head>
<title>todo</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="/underscore-master/underscore-min.js"></script>
<script src="todo.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
</head>
<body>
<div ng-controller="todoCtrl">
<h2>Total todos: {{todos.length}}</h2>
<ul class="unstyled">
<li ng-repeat="todo in todos">
<span>{{todo.text}}</span>
</li>
</ul>
</div>
<form class="form-horizontal">
<input type="text" ng-model="todoText">
<button class="btn" ng-click="addTodo()"><i class="icon-plus">Add</i></button>
</form>
</body>
</html>
It should insert new text in my array, but when i'm clikcking on the button nothing happens, and no error in console, i realy can't understand why?
The ng-click event is out of the controller's scope. The quick answer is to move ng-controller="todoCtrl" to an enclosing/outer element, which is body in this case.
Move the ng-controller attribute to the <body> - so that it incorporates the form and the ng-click event. For example:
var app = angular.module('todoApp', []);
app.controller('todoCtrl', ['$scope', function($scope) {
$scope.todos = [
{
text: "Learn AngularJs"
},
{
text: "Build App"
}
];
$scope.addTodo = function() {
$scope.todos.push({text: $scope.todoText});
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="todoApp">
<body ng-controller="todoCtrl">
<div>
<h2>Total todos: {{todos.length}}</h2>
<ul class="unstyled">
<li ng-repeat="todo in todos">
<span>{{todo.text}}</span>
</li>
</ul>
</div>
<form class="form-horizontal">
<input type="text" ng-model="todoText">
<button class="btn" ng-click="addTodo()"><i class="icon-plus">Add</i></button>
</form>
</body>
</html>
The model and functions should be in scope to be used, so you need to have addTodo function called within todoCtrl scope. Just add a wrapper and have the controller there.
var app = angular.module('todoApp', []);
app.controller('todoCtrl', ['$scope', function($scope) {
$scope.todos = [
{
text: "Learn AngularJs"
},
{
text: "Build App"
}
];
$scope.addTodo = function() {
$scope.todos.push({text: $scope.todoText});
};
}]);
<html ng-app="todoApp">
<head>
<title>todo</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="/underscore-master/underscore-min.js"></script>
<script src="todo.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
</head>
<body>
<div ng-controller="todoCtrl" class="wrapper">
<div>
<h2>Total todos: {{todos.length}}</h2>
<ul class="unstyled">
<li ng-repeat="todo in todos">
<span>{{todo.text}}</span>
</li>
</ul>
</div>
<form class="form-horizontal">
<input type="text" ng-model="todoText">
<button class="btn" ng-click="addTodo()"><i class="icon-plus">Add</i></button>
</form>
<div>
</body>
</html>

Angular : Bootstrap giving error in console

Here is my code :
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<script type="text/javascript" src="./angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
var app1 = angular.module('myApp1', []);
app.controller('myCtrl', function($scope) {
$scope.firstName = "sparsh";
$scope.lastName = "khandelwal";
});
</script>
<title>Home Page</title>
</head>
<body>
<div ng-app="myApp" ng-init="name='Sparsh'">
<div ng-controller="myCtrl">{{firstName}}</div>
<p>
Name : <input type="text" ng-model="name">
</p>
<h1>Hello {{name}}</h1>
</div>
<div ng-app="myApp1" ng-init="names=['Jani','Hege','Kai']">
<ul>
<li ng-repeat="x in names">{{x}}</li>
</ul>
</div>
<script type="text/javascript">
angular.bootstrap(document, ['myApp1','myApp']);
</script>
</body>
</html>
Although i can see the expected output, but at the same time facing console error.
here is the description of error
(while i click on the url)
it says it already bootstrapped so i remove the 'myApp' from .bootstrap function, but that didnt work.
Please help.
You are doing both ng-app declarations and angular.bootstrap(document, ['myApp1','myApp']);.
You need to choose only one method, otherwise you get the well descripted error of multiple bootstrapped applications.
The problem is as explained in the previous comments, the automatic and manual initialization of modules.
Since you want to initialize them separately for each elements then try an approach like
<div data-app="myApp" ng-init="name='Sparsh'">
<div ng-controller="myCtrl">{{firstName}}</div>
<p>
Name : <input type="text" ng-model="name"/>
</p>
<h1>Hello {{name}}</h1>
</div>
<div data-app="myApp1" ng-init="names=['Jani','Hege','Kai']">
<ul>
<li ng-repeat="x in names">{{x}}</li>
</ul>
</div>
then
var app = angular.module('myApp', []);
var app1 = angular.module('myApp1', []);
app.controller('myCtrl', function ($scope) {
$scope.firstName = "sparsh";
$scope.lastName = "khandelwal";
});
var els = document.querySelectorAll('[data-app]');
for (var i = 0; i < els.length; i++) {
angular.bootstrap(els[i], [els[i].dataset.app]);
}
Demo: Fiddle

Trying to Show Length Value of listArray

I'm learning how to develop with AngularJS for the first time for a class and I am trying to understand why I'm not getting an updated value of the length property and was hoping someone could help me understand why my code is not working and what I should be doing for it to update.
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<title>Grocery List</title>
<script src="js/angular.min.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app>
<h1>My Grocery List</h1>
<div ng-controller="MYController">
<input type="text" ng-model="listItem" placeholder="Add Grocery Item" />
<input type="submit" ng-click="addItem()" value="Save" />
<h2>Items</h2>
<ul ng-show="itemArray.length">
<li ng-repeat="listItem in itemArray">
{{ listItem }}
<buton ng-click="deleteItem(listItem)">X</buton>
</li>
</ul>
</div>
</body>
</html>
Code in app.js
function MYController($scope) {
$scope.listItem;
$scope.itemArray = [];
$scope.addItem = function() {
$scope.itemArray.push($scope.listItem);
$scope.listItem = '';
}
$scope.deleteItem = function(deletedItem) {
var idx = $scope.itemArray.indexOf(deletedItem);
$scope.itemArray.splice(idx, 1);
}
}
In Angular when you make controller then it need to assign with a module
So here you will made your controller in js like below
angular.module('todoApp', [])
.controller('MYController', ['$scope', function($scope) {
$scope.listItem;
$scope.itemArray = [];
$scope.addItem = function() {
$scope.itemArray.push($scope.listItem);
$scope.listItem = '';
}
$scope.deleteItem = function(deletedItem) {
var idx = $scope.itemArray.indexOf(deletedItem);
$scope.itemArray.splice(idx, 1);
}
});
And in HTML bootstrap angular like below in body tag and use your controller
<body ng-app="todoApp">
See here for reference https://angularjs.org/#add-some-control
I think there may be some confusion between the listItem in ng-model="listItem" and ng-repeat="listItem in itemArray". Try changing the second one to a different variable name like this:
<li ng-repeat="item in itemArray">
{{ item }}
<button ng-click="deleteItem(item)">X</button>
</li>
Also, change that first line in your controller $scope.listItem; to $scope.listItem = '';.
assign module to angular app using this code:
var app = angular.module('plunker', [])
and
<html ng-app="plunker">
see plunker

Categories