why does my form submission not work? - angularjs

I just want to use the two way binding to update my list by adding new elements to it. I don't understand why i can't do it? am i missing a major concept?
index.html
<!DOCTYPE html>
<html>
<head>
<title>NgRailsTodoList</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body ng-app="todoApp" ng-controller="MainCtrl">
<div class="container">
<div class="content-container clearfix">
<div class="col-md-12">
<h1 class="content-title text-center">Todo</h1>
<div ng-repeat="list in lists">
<h3>{{list.name}}</h3>
<div ng-repeat="task in list.tasks">
<h5><input type="checkbox" ng-checked="task.completed">{{ task.body }}</h5>
</div>
<div>
</div>
<form ng-submit="addList()">
<input type="text" ng-model="name"></input>
<button type="submit"> New List </button>
</form>
</div>
</div>
</body>
</html>
app.js
angular.module('todoApp', ['ui.router', 'templates'])
.factory('lists',[ function () {
var o = { lists: [{ name: "groceries", completed: false,
tasks: [{body: "buy fish",completed: true},
{body: "buy sushi",completed: false},
{body: "buy bread",completed: true}]}]
};
return o;
}])
.controller('MainCtrl', [
'$scope','lists',
function($scope,lists){
console.log(lists);
$scope.lists = lists.lists;
$scope.addList = function(){
$scope.lists.push({name: $scope.name, completed: false})
// console.log(this.name);
// $scope.name = '';
};
}
]);

The issue is in the markup.
<h5><input type="checkbox" ng-checked="task.completed">{{ task.body }}</h5>
</div>
<div>
</div>
the second <div> should be a close tag </div>
here is a working example http://codepen.io/mkl/pen/KzEmwP

Related

Why $scope object couldn't display the data from my controller in view2.html

I'm new Angular JS.I stuck with $routeProvider example.I'm routing view1 and view2 using $routeProvider.when from main.html.View1 is working fine. View2 is not getting the $scope object.
View1 is displaying the customers data. But View2 is not working.
Did i miss something in the code.
##Main.html:
<html ng-app="demoApp">
<title>AngularJS Routing</title>
<body>
<div>
<ng-view></ng-view>
</div>
<script src="angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.28//angular-route.min.js"></script>
var demoApp = angular.module('demoApp', ['ngRoute']);
demoApp.config(function($routeProvider)
{
$routeProvider
.when('/',{controller:'Controller1',templateUrl:'view1.html'})
.when('/view2',{controller:'Controller1',templateUrl:'view2.html'})
.otherwise({redirectTo:'/view1.html'});
});
demoApp.controller("Controller1", function($scope)
{
$scope.customers = [
{custname:"A",city:"Irving"},
{custname:"B",city:"Grapevine"},
{custname:"C",city:"Little Elm"},
{custname:"D",city:"Frisco"},
{custname:"E",city:"Mckinney"},
{custname:"F",city:"Prosper"}
];
$scope.addItem = function(){
$scope.customers.push({
custname:$scope.newCustomername,
city:$scope.newCustomercity
});
}
});
</script>
</body>
</html>
##view1.html:
<div class="container">
<h2>Welcome to Directive - Data Binding</h2>
Customer Name: <input type="text" data-ng-model="newCustomername">
Customer City: <input type="text" data-ng-model="newCustomercity">
<button ng-click="addItem()">Add Item</button>
<li ng-repeat="name in customers">
Customer Name: {{ name.custname }} <br/>
Customer City: {{ name.city }}
</li>
View 2
</div>
##View2.html:
<div class="container">
<h3> View 2</h3>
<li ng-repeat="name in customers">
Customer Name: {{ name.custname }} <br/>
Customer City: {{ name.city }}
</li>
</div>

What did I do wrong with my todo app?

My todo app just doesn't work. It doesn't even display any pre-existing todo tasks on screen. Nor is it able to add or remove any items.
All it renders is the input form and submit button.
Why is that? Please advise!
var app = angular.module('todoApp',[])
app.controller('TodoController',['$scope', function($scope){
$scope.todos = [
{task: 'Learn AngularJs', done: false},
{task:'Feed the dog', done: false},
{task: 'Water the cactus', done: true}]
$scope.addTodo = function(){
$scope.todos.push({task: $scope.todoText, done: false});
$scope.todoText ='';
console.log($scope.todos);
}
$scope.removeTodo = function(){
var oldTodos = $scope.todos;
$scope.todos = [];
angular.forEach(oldTodos, function(todo) {
if (!todo.done) $scope.todos.push(todo);
});
}
}])
<!DOCTYPE html>
<html ng-app="todoApp">
<head>
<meta charset="utf-8"/>
<script src="bower_components/angular/angular.min.js"></script>
<script type="text/javascript" src="todo.js"></script>
<style>
.done-true{
text-decoration: line-through;
color: grey;
}
</style>
</head>
<body >
<div ng-controller="TodoController as todoList">
<ul class="unstyled">
<li ng-repeat="todo in todoList.todos">
<input type="checkbox" ng-model="todo.done">
<span class="done-{{todo.done}}">{{todo.task}}</span>
</li>
</ul>
<form ng-submit="todoList.addTodo()">
<input type="text" placeholder="Add a new todo" ng-model="todoList.todoText">
<input type="button" type="submit" value="add">
</form>
<button ng-click="todoList.removeTodo()">Delete All</button>
</div>
</body>
</html>
remove todoList. while accessing variables and methods..
So your code should look like
<!DOCTYPE html>
<html ng-app="todoApp">
<head>
<meta charset="utf-8"/>
<script src="bower_components/angular/angular.min.js"></script>
<script type="text/javascript" src="todo.js"></script>
<style>
.done-true{
text-decoration: line-through;
color: grey;
}
</style>
</head>
<body >
<div ng-controller="TodoController">
<ul class="unstyled">
<li ng-repeat="todo in todos">
<input type="checkbox" ng-model="todo.done">
<span class="done-{{todo.done}}">{{todo.task}}</span>
</li>
</ul>
<form>
<input type="text" placeholder="Add a new todo" ng-model="todoText">
<input type="button" ng-click="addTodo()" type="submit" value="add">
</form>
<button ng-click="todoList.removeTodo()">Delete All</button>
</div>
</body>
</html>
You are using MVVM method in your context so if you use controllerAs you need to use VM varibale is a scope in the controller instead of $scope variable. If you have any issues about MVC and MVVM please go through the reference link
http://www.dotnettricks.com/learn/designpatterns/understanding-mvc-mvp-and-mvvm-design-patterns
http://www.meritsolutions.com/mobile-development/mvvm-architectural-pattern-angularjs/
var app = angular.module('todoApp',[])
app.controller('TodoController',['$scope', function($scope){
var vm = this;
vm.todos = [
{task: 'Learn AngularJs', done: false},
{task:'Feed the dog', done: false},
{task: 'Water the cactus', done: true}]
vm.addTodo = function(){
if(vm.todoText)
vm.todos.push({task: vm.todoText, done: false});
vm.todoText ='';
console.log(vm.todos);
}
vm.removeTodo = function(){
var oldTodos = vm.todos;
vm.todos = [];
angular.forEach(oldTodos, function(todo) {
if (!todo.done) vm.todos.push(todo);
});
}
}])
.done-true{
text-decoration: line-through;
color: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="todoApp" ng-controller="TodoController as todoList">
<ul class="unstyled">
<li ng-repeat="todo in todoList.todos">
<input type="checkbox" ng-model="todo.done">
<span class="done-{{todo.done}}">{{todo.task}}</span>
</li>
</ul>
<form >
<input type="text" placeholder="Add a new todo" ng-model="todoList.todoText">
<input type="button" type="button" value="add" ng-click="todoList.addTodo()">
</form>
<button ng-click="todoList.removeTodo()">Delete All</button>
</div>

How to get the checked item inside a ng-repeat using angular?

I want to get the check item from a list withing a ng-repeat in angular. Once the item is checked I want to put that checked item to another list.Here is my code so far.
<div class="col-lg-12" data-ng-repeat="user in users track by $index">
<div class="col-lg-12">
<div class="col-lg-3"> {{user.name}} </div>
<div class="col-lg-3">
<input type="checkbox" data-ng-checked="selectUser(user)" data-ng-model="user.isSelected" />
</div>
</div>
</div>
<div class="col-lg-12" data-ng-repeat="selectedUser in selectedUsers track by $index">
<div class="col-lg-12">
<div class="col-lg-3"> {{selectedUser.name}} </div>
<div class="col-lg-3">
</div>
</div>
</div>
This is my controller function to get the checked users.
$scope.selectUser = function(user){
if (user.isSelected) {
if ($scope.selectedUsers.indexOf(user.id) === -1) {
$scope.selectedUsers.push(user);
}
}else {
var index = $scope.selectedUsers.indexOf(user.id);
if ($scope.selectedUsers.indexOf(user.id) != -1) {
$scope.selectedUsers.splice(index, 1);
}
}
When I check a checkbox, all the users value will be passed to selectUsers() function. And it will give incorrect result. I want only to get the selected users. How can I do this?
Some mistakes you made here
You are using ng-check in wrong way.
Try this
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.allUsers = [{
id:0,
name:'john',
age:26,
selectedUser:true
},{
id:1,
name:'isha',
age:23,
selectedUser:false
},{
id:2,
name:'scott',
age:34,
selectedUser:true
},{
id:3,
name:'riya',
age:26,
selectedUser:false
},{
id:4,
name:'Adam',
age:5,
selectedUser:true
},{
id:5,
name:'doe',
age:56,
selectedUser:true
},{
id:6,
name:'Jack',
age:22,
selectedUser:true
},{
id:7,
name:'robin',
age:11,
selectedUser:true
}];
$scope.selectedUsers = [];
$scope.selectUser = function(user){
if (user.isSelected) {
$scope.selectedUsers.push(user);
}else {
for (var i = 0; i < $scope.selectedUsers.length; i++) {
if ($scope.selectedUsers[i].id == user.id) {
$scope.selectedUsers.splice(i, 1);
}
}
}
}
})
</script>
</head>
<body style="margin-top: 100px" ng-app="myApp" ng-controller="myCtrl">
<div class="col-lg-12" data-ng-repeat="user in allUsers track by $index">
<div class="col-lg-12">
<div class="col-lg-3"> {{user.name}} </div>
<div class="col-lg-3">
<input type="checkbox" ng-change="selectUser(user)" data-ng-model="user.isSelected" />
</div>
</div>
</div>
selected users
<div class="col-lg-12" data-ng-repeat="user in selectedUsers track by $index">
<div class="col-lg-12">
<div class="col-lg-3"> {{user.name}} </div>
<div class="col-lg-3">
</div>
</div>
</div>
</body>
</html>
Try this I think u need like this
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module('MyApp', [])
app.controller('MyController', function ($scope, $window) {
$scope.Fruits = [{
FruitId: 1,
Name: 'Apple',
Selected: false
}, {
FruitId: 2,
Name: 'Mango',
Selected: false
}, {
FruitId: 3,
Name: 'Orange',
Selected: false
}];
$scope.GetValue = function () {
var message = "";
for (var i = 0; i < $scope.Fruits.length; i++) {
if ($scope.Fruits[i].Selected) {
var fruitId = $scope.Fruits[i].FruitId;
var fruitName = $scope.Fruits[i].Name;
message += "Value: " + fruitId + " Text: " + fruitName + "\n";
}
}
$window.alert(message);
}
});
</script>
<div ng-app="MyApp" ng-controller="MyController">
<div ng-repeat="fruit in Fruits">
<label for="chkCustomer_{{fruit.FruitId}}">
<input id="chkCustomer_{{fruit.FruitId}}" type="checkbox" ng-model="fruit.Selected" />
{{fruit.Name}}
</label>
</div>
<br />
<br />
<input type="button" value="Get" ng-click="GetValue()" />
</div>
</body>
</html>

Angular Bootstrap UI accordion not working as expected

I am using accordion component of Angular Bootstrap UI. The first accordion is expanded by default. When user add new accordion then first accordion should collapse and newly added accordion should be expand. When user clicks any accordion then it should be expanded and collapse rest of the accordions. User can add more than one accordion.
How can I achieve this?
I'm newbie to angular and Angular Bootstrap UI.
What I have done so far
Ctrl.js
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('AccordionDemoCtrl', function($scope) {
$scope.oneAtATime = true;
$scope.groups = [{
title: 'Dynamic Group Header - 1',
content: 'Dynamic Group Body - 1'
}, {
title: 'Dynamic Group Header - 2',
content: 'Dynamic Group Body - 2'
}, {
title: 'Dynamic Group Header - 3',
content: 'Dynamic Group Body - 3'
}];
$scope.status = {
isCustomHeaderOpen: false,
isFirstOpen: true,
isFirstDisabled: false
};
// work permit form
$scope.transforms = [{
name: "transform",
id: 1,
wpformfields: [{
employee: '',
admount: ''
}]
}];
$scope.addtransactionForm = function(transform) {
$scope.currentnum = transform.wpformfields.length;
//alert("hello");
transform.wpformfields.push({
employee: '',
amount: ''
});
};
});
index.html
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.1.3.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="AccordionDemoCtrl" class="container">
<br>
<br>
<br>
<div class="row">
<div class="col-md-10">
<form role="form" id="$index" class="base-form" ng-repeat="form in transforms track by $index">
<input type="checkbox" ng-model="oneAtATime" style="display:none">
<uib-accordion close-others="oneAtATime">
<div uib-accordion-group class="panel-default" is-open="status.isFirstOpen" is-disabled="status.isFirstDisabled" ng-repeat="itemfield in form.wpformfields track by $index">
<uib-accordion-heading>
Transaction <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.isFirstOpen, 'glyphicon-chevron-right': !status.isFirstOpen}"></i>
</uib-accordion-heading>
<div class="md-col-10 main-container">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Employee name </label>
<input type="text" class="form-control" name="employee" id="employee" ng-model="itemfield.employee">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Amount </label>
<input type="text" class="form-control" name="amount" id="amount" ng-model="itemfield.amount">
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button type="submit" class="btn btn-default pull-right" ng-click="addTransaction(form, $index)"><i class="fa fa-floppy-o"></i> Save record</button>
</div>
</div>
</div>
</div>
</uib-accordion>
<div class="row">
<div class="col-md-12 col-md-offset-5">
<a class="btn btn-danger" ng-click="addtransactionForm(form)"><i class="fa fa-user-plus fa-lgt" ></i> Add new transaction record</a>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
Plunker available link
There is modified version which should satisfy your needs. Basically, you need to add isOpen and isDisabled property for each accordion then set isOpen to true for new accordion, others will be closed automatically.

filter not work properly with group by in angular js

When i have search with comedy then its also give the result while we want
filter only with title not with category. so count and result will be wrong.
can any body suggest me how can we develop the custom filter with group by or have any other way on same.
my Code is
<script>
var myApp = angular.module('myApp', ['angular.filter']);
myApp.controller("MyController", function ($scope)
{
$scope.movies =
[
{ title: 'The Matrix', rating: 7.5, category: 'Action' },
{ title: 'Focus', rating: 6.9, category: 'Comedy' },
{ title: 'The Lazarus Effect', rating: 6.4, category: 'Thriller' },
{ title: 'Everly', rating: 5.0, category: 'Action' },
{ title: 'Maps to the Stars', rating: 7.5, category: 'Drama' }
];
});
</script>
<div ng-controller="MyController">
<div class="searchBar">
<input type="text" name="title" ng-model="title" placeholder="Search..." />
</div>
<ul class="angularList" ng-repeat="(key, value) in movies | groupBy: 'category'">
<h3>{{ key }} ({{ value.length }})</h3>
<li ng-repeat="movie in value | filter:title">
{{ movie.title }}<br />
<div class="rating_box">
<div class="rating" style="width:{{movie.rating*10}}%"></div>
</div>
</li>
</ul>
</div>
the solution found on: Solution
You'r script:
myApp.filter('groupBy', function ($timeout) {
return function (data, key) {
if (!key) return data;
var outputPropertyName = '__groupBy__' + key;
if(!data[outputPropertyName]){
var result = {};
for (var i=0;i<data.length;i++) {
if (!result[data[i][key]])
result[data[i][key]]=[];
result[data[i][key]].push(data[i]);
}
Object.defineProperty(data, outputPropertyName, {enumerable:false, configurable:true, writable: false, value:result});
$timeout(function(){delete data[outputPropertyName];},0,false);
}
return data[outputPropertyName];
};
})
In your HTML:
<div ng-controller="MyController as myCtrl">
<div class="searchBar">
<input type="text" name="title" ng-model="title" placeholder="Search..." />
</div>
<ul class="angularList" ng-repeat="(key, value) in (myCtrl.movies | groupBy: 'myCtrl.category')">
<h3>{{ key }} ({{ value.length }})</h3>
<li ng-repeat="movie in value | filter:title">
{{ movie.title }}<br />
<div class="rating_box">
<div class="rating" style="width:{{movie.rating*10}}%"></div>
</div>
</li>
</ul>
</div>
I have tested your code and it's working fine for me. Please check this URL https://jsbin.com/tapeke/edit?html,js,output
i have also tested your code it's working fine...
below code is working code
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.4.7/angular-filter.js"></script>
</head>
<body>
<div ng-controller="MainController">
<div class="searchBar">
<input type="text" name="title" ng-model="title" placeholder="Search..." />
</div>
<ul class="angularList" ng-repeat="(key, value) in movies | groupBy: 'category'">
<h3>{{ key}} ({{ value.length}})</h3>
<li ng-repeat="movie in value| filter:title">
{{ movie.title}}<br />
<div class="rating_box">
<div class="rating" style="width:{{movie.rating * 10}}%"></div>
</div>
</li>
</ul>
</div>
<script>
angular.module('myApp', ['angular.filter'])
.controller('MainController', function ($scope) {
$scope.movies =
[
{title: 'The Matrix', rating: 7.5, category: 'Action'},
{title: 'Focus', rating: 6.9, category: 'Comedy'},
{title: 'The Lazarus Effect', rating: 6.4, category: 'Thriller'},
{title: 'Everly', rating: 5.0, category: 'Action'},
{title: 'Maps to the Stars', rating: 7.5, category: 'Drama'}
];
});
</script>

Resources