I want to update my view(an input form) to add products to database. For a single product I am able to add it by making it into an array, but now I want to add multiple products and with the click of a button "Add more Product", a similar view(form) is to be generated below the existing form, and this can go on multiple times(to be determined at run time). Now I have two problems:
1. How to update my view with every (Add more Product)button click. Is it done by maintaining some count?
2. How to add multiple product values from each of the forms into the the array of object.
$scope.onClick = function () {
$scope.productData =
{
name: $scope.name,
description: $scope.description,
price: $scope.price,
image: $scope.image,
tags: $scope.tags,
partner_id: $scope.partner_id,
};
}
Example Code
There are a ton of ways to do this. I made this sample plunker that shows a simple option of toggling a form div, adding data in the form, then pushing the resulting form object to the primary products array.
EDIT: I refactored my plunk and snippet to use a Javascript class and constructor. Cloning a master object as shown below is another way to perform this task.
https://embed.plnkr.co/IsNifSaF8jE7oOog29dK/
(See the full snippet at the bottom of this answer.)
Explanation
In your code, you are using $scope on all of your object properties. What you should actually do is create one top-level scope array that is the result of your products retrieval from the server. I would actually create a JavaScript constructor / class that matches the product object you need in the database (for brevity, I just created a "master" object and a cloned "newProduct" object to make edits to):
// Sample Product Object
$scope.newProduct= {
name: "",
description: "",
price: 0.00,
image: "",
tags: [],
partner_id: 0
};
You can bind your $scope.newProduct object to the form with ng-model.
<!-- ==== Simplified Form ==== -->
<form class="form" ng-submit="submitNewProduct()">
<div class="form-group">
<label>Product Name: </label>
<input class="form-control" type="text" ng-model="newProduct.name" >
</div>
<input type="submit" class="btn btn-info" />
</form>
Now when you submit the new product data, you can manipulate it however you need to in the controller (via the $scope.submitNewProduct() function). Once the object is successfully inserted into your database and you're done manipulating the data, you can push the finalized "new product" object into the products array. AngularJs will update the view for you (bound objects via ng-model are being watched for changes) once you add the new product to the array:
// If server update is successful, add new product to products array
$scope.products.push($scope.newProduct);
If you aren't using a constructor, just make sure to note that I reset the $scope.newProduct object back to default values so it doesn't carry over any new changes when you open the new product form again.
// Reset placeholder product
$scope.newProduct = $scope.masterProduct;
Helpful Resources
Tutorial Vids: https://youtu.be/MzqkIZLkBsU
Javascript Constructors: https://www.w3schools.com/js/js_object_constructors.asp
ngRepeat Examples: https://www.w3schools.com/angular/ng_ng-repeat.asp
Snippet
(function() {
"use strict";
var app = angular.module("myApp", []);
app.controller("myController", myController);
myController.$inject = ["$scope", "$timeout", "$filter"];
function myController($scope, $timeout, $filter) {
$scope.loading = false;
class Product {
constructor(_name, _description, _price) {
this.id = this.getNewId();
this.name = _name;
this.description = _description;
this.price = _price;
this.image = "https://www.thesweetexplosion.co.uk/wp-content/uploads/2013/06/product-placeholder.jpg";
this.tags = [];
this.partner_id = 0;
}
getNewId() {
var latestId = $scope.products[$scope.products.length - 1].id
return latestId + 1;
}
}
// Pretending we received these products received from the database...
$scope.products = [{
id: 0,
name: "product_1",
description: "product_1 description",
price: 52.23,
image: "https://raspberrypi.dk/wp-content/uploads/2014/07/raspberry-pi-model-b-plus1.png",
tags: [],
partner_id: 345214967
}, {
id: 1,
name: "product_2",
description: "product_2 description",
price: 46.23,
image: "https://modtronix.com.au/wp-content/uploads/enc-rpi3-official_bottom_ll-100x100.jpg",
tags: [],
partner_id: 514852924
}];
// Add new Products by using this base object
$scope.placeholderProduct = {
id: 0,
name: "",
description: "",
price: 0.00,
image: "https://www.thesweetexplosion.co.uk/wp-content/uploads/2013/06/product-placeholder.jpg",
tags: [],
partner_id: 0
};
$scope.createNewProduct = function(){
$scope.newProduct = new Product("", "", 0);
}
$scope.submitNewProduct = function() {
// DO SERVER UPDATING HERE
// Show loading
$scope.updating = true;
// Simulate server update
$timeout(function() {
// If server update is successful, add new product to products array
$scope.products.push($scope.newProduct);
// Reset submit button
$scope.updating = false;
// Reset placeholder product
$scope.newProduct = {};
// Hide products form
$scope.addProductForm = false;
}, 1000);
}
}
})();
.productImg {
width: 50px;
height: 50px;
}
.prodForm {
margin-top: 15px;
margin-bottom: 15px;
;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.1/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://use.fontawesome.com/releases/v5.0.9/js/all.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="myApp" ng-controller="myController">
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="jumbotron text-center">
<h3>AngularJS (1.3.1) - Instantiating Products with ES6 Class Constructor</h3>
</div>
</div>
</div>
<!-- New Product Form - Toggled with addProductForm -->
<div class="col-xs-12">
<button type="button" class="btn btn-sm btn-success" ng-click="createNewProduct(); addProductForm = !addProductForm" ng-show="!addProductForm">
<span class="glyphicon-plus"> Add New Product</span>
</button>
<button type="button" class="btn btn-sm btn-danger" ng-click="addProductForm = !addProductForm" ng-show="addProductForm">
<span>Clear</span>
</button>
</div>
<div class="col-xs-12 well prodForm" ng-show="addProductForm">
<form class="form" ng-submit="submitNewProduct()">
<div class="form-group">
<label>Product Name: </label>
<input class="form-control" type="text" ng-model="newProduct.name" >
</div>
<div class="form-group">
<label>Description: </label>
<input class="form-control" type="text" ng-model="newProduct.description" />
</div>
<div class="form-group">
<label>Price: </label>
<input class="form-control" type="number" min="0.01" step="0.01" ng-model="newProduct.price" format="currency" />
</div>
<div class="form-group">
<label>Partner Id: </label>
<input class="form-control" type="number" ng-model="newProduct.partner_id" />
</div>
<input type="submit" class="btn btn-info" ng-show="!updating" />
<button type="button" class="btn btn-info" ng-show="updating"><i class="fa fa-spinner fa-spin"></i> Updating...</button>
</form>
</div>
<!-- Primary Products Table -->
<div class="col-xs-12">
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Price</th>
<th>Image</th>
<th>Tags</th>
<th>Partner Id</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="product in products track by $index">
<td>{{ product.name }}</td>
<td>{{ product.description }}</td>
<td>{{ product.price | currency }}</td>
<td>
<img class="productImg" ng-src="{{ product.image }}" alt="{{ product.name }} img" />
</td>
<td>{{ product.tags }}</td>
<td>{{ product.partner_id }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
Related
I have an angular app, and an index.html with an ng-view that renders to different views partials/persons.html and partials/newPerson.html.
when i add a new person to the $scope.persons in my controller via the newPerson.html the $scope.persons is updated, but it dosn´t updated the table in the partials/persons.html. if i copy/paste the table into partials/newPerson.html the table is updated automatically. I cant seem to wrap my head around why? they are using the same controller...?
thank´s in advance for your help :)
js/app.js
var app = angular.module('app',['ngRoute']);
app.config(function($routeProvider){
$routeProvider
.when('/persons',{
templateUrl:'partials/persons.html',
controller:'PersonCtrl'
})
.when('/newperson',{
templateUrl:'partials/newPerson.html',
controller:'PersonCtrl'
})
.otherwise({
redirectTo: '/'
});
});
app.controller('PersonCtrl',['$scope', function($scope){
var persons = [
{
id: 1
,name: "Jens",
age : 18}
,{
id: 2,
name: "Peter",
age : 23
}
,{
id: 3
,name: "Hanne"
,age : 23
}
];
$scope.persons = persons;
$scope.nextId = 4;
$scope.savePerson = function(){
if($scope.newPerson.id === undefined)
{
$scope.newPerson.id= $scope.nextId++;
$scope.persons.push($scope.newPerson);
}else{
for (var i = 0; i < $scope.persons.length; i++) {
if($scope.persons[i].id === $scope.newPerson.id){
$scope.persons[i] = $scope.newPerson;
break;
}
}
}
$scope.newPerson = {};
};
index.html
<html ng-app="app" ng-controller="PersonCtrl">
<head>
<title>Routing</title>
<link rel="stylesheet" href="css/styles.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular-route.js"></script>
<script src="https://code.angularjs.org/1.4.7/i18n/angular-locale_da.js"></script>
<script src="angularSrc/app.js"></script>
</head>
<body>
<br>
<div class="container">
<header>
<h1>People Routing</h1>
<nav>
persons
new person
</nav>
</header>
<div ng-view="ng-view">
</div>
</div>
</body>
partials/persons.html
<h3>Persons</h3>
<table >
<thead>
<tr>
<td>Id</td>
<td>name</td>
<td>age</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="p in persons">
<td>{{p.id}} </td>
<td>{{p.name}} </td>
<td>{{p.age}} </td>
</tr>
</tbody>
</table>
partials/newPerson.html
<div >
<h1>New person</h1>
<form class="form-horizontal">
<fieldset>
<div class="form-group">
<input type="text" ng-model="newPerson.name" model="newPerson.name" class="form-control" id="year" placeholder="name">
</div>
<div class="form-group">
<input type="number" ng-model="newPerson.age" model="newPerson.age" class="form-control" id="age" placeholder="age">
</div>
</fieldset>
</form>
<button type="submit" ng-click="savePerson()" >Save</button>
<h2>nextId: {{nextId}}</h2>
</div>
The problem is that you aren't realizing that each use of controller creates new instance.
The scope is destroyed when you leave a controller so if you add to the scope in one instance , that change will be lost when you load controller again on your other route.
You need to use a service to persist the data during the life of each page load.
Simple service example:
app.factory('PersonService', function () {
var persons = [{
id: 1,
name: "Jens",
age: 18
}, {
...
}, {
...
}];
return {
persons: persons
}
});
Then inject in controller and use the service data in controller
app.controller('PersonCtrl',['$scope','PersonService', function($scope,PersonService){
$scope.persons = PersonService.persons;
i'm working on an angular web app and i'm stuck in a part of it.i'm trying to update an angular model by choosing an item in a bootstrap carousel.i mean that if i select an image from the bootstrap carousel, the image's link will be put in the form used to update the model.is it possible to do it?this is the code i'm trying to make working
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.0.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="Interaction_Ctrl">
<form>
<table>
<tr>
<td>Image URL:</td>
<td>
<input type="url" placeholder="http://reelyactive.com/images/barnowl.jpg" ng-model="person.image" ng-change='change()' class="form-control" />
</td>
</tr>
<tr>
<td>
<carousel>
<slide ng-repeat="slide in slides" active="slide.active" ng-model="person.image" ng-change='change()'>
<img ng-src="{{slide.image}}" style="height:100px; margin:auto">
<div class="carousel-caption">
<h4>Slide {{$index}}</h4>
<p>{{slide.text}}</p>
</slide >
</carousel>
</td>
</tr>
</table>
</form>
</div>
var mymodule = angular.module("jsonerator", ['ui.bootstrap']);
mymodule.controller("Interaction_Ctrl", function ($scope) {
$scope.slides = [];
$scope.slides.push({
text: 'barnowl',
image: 'http://reelyactive.com/images/barnowl.jpg'
});
$scope.slides.push({
text: 'barnacles',
image: 'http://reelyactive.com/images/barnacles.jpg'
});
$scope.slides.push({
text: 'barterer',
image: 'http://reelyactive.com/images/barterer.jpg'
});
$scope.slides.push({
text: 'chickadee',
image: 'http://reelyactive.com/images/chickadee.jpg'
});
$scope.slides.push({
text: 'starling',
image: 'http://reelyactive.com/images/starling.jpg'
});
function changeKeyValue() {
for(var key in $scope.person) {
if($scope.person.hasOwnProperty(key)) {
if(!$scope.person[key].length) {
delete $scope.person_ld["#graph"][0]["schema:" + key];
}
else {
$scope.person_ld["#graph"][0]["schema:" + key] = $scope.person[key];
}
}
}
}
$scope.change = function() {
changeKeyValue();
}
});
});
If you place the input url element somewhere within the ng-repeat, the input will update as the slides change. Right now the issue is the scope {{slide.image}} is within each <scope> element, so the input does cannot utilize the model attribute.
<carousel>
<slide ng-repeat="slide in slides" active="slide.active" ng-model="person.image">
<input type="url" placeholder="http://reelyactive.com/images/barnowl.jpg" ng-model="person.image" class="form-control" />
<br>
<br>
<img ng-src="{{slide.image}}" style="height:100px; margin:auto">
<div class="carousel-caption">
<h4>Slide {{$index}}</h4>
<p>{{slide.text}}</p>
</slide >
</carousel>
You can adjust CSS or add additional <br/> to separate as needed. Plunker below. Let me know if that helps.
http://plnkr.co/edit/Kd23U1ercuqc2ACpQEZH?p=preview
First of all I am new to angularjs.
I want to make a simple / quick refference betweeen my anchors and paragraphs>inputs, depending on what I clicked in my angular web app.
I generate 3 table rows with 1 table data with the ng-repeat. After this, when I click one of the anchors my toggleDetails(todo.id,todo.nume,todo.prenume) triggers and I update my next below input values (#inputId, #inputNume, #inputPrenume) with basic javascript. I feel like I m doing it hard way. Can I use less code like some angularjs directives ?(I`m using a Yeoman framework) So, this is my HTML:
<div class="container" controller="AboutCtrl">
<h2>Lista persoane</h2>
<table>
<tr>
<th>Nume si prenume</th>
</tr>
<tr class="form-group " ng-repeat="todo in todos">
<td>
<a href ng-click="toggleDetails(todo.id,todo.nume,todo.prenume)">
<input type="text" ng-model="todo.nume" class="form-control">
</a>
</td>
</tr>
</table>
<div ng-hide="hideDetails">
<p>Id:<input type="text" id="inputId"/></p><br>
<p>Nume:<input type="text" id="inputNume"/></p><br>
<p>Prenume:<input type="text" id="inputPrenume"/></p><br>
</div>
</div>
About.js file
.controller('AboutCtrl', function ($scope, AfisareDateService) {
$scope.todos = [{
id: 1,
nume: 'name1',
prenume: 'name2'},{
id: 2,
nume: 'name3',
prenume: 'nam4'}, {
id: 3,
nume: 'name5',
prenume: 'name6'
}];
$scope.hideDetails = true;
$scope.toggleDetails = function(id,nume,prenume) {
$scope.hideDetails = !$scope.hideDetails;
var x = document.getElementById('inputId');
var y = document.getElementById('inputNume');
var z = document.getElementById('inputPrenume');
x.value = id;
y.value = nume;
z.value = prenume;
});
few changes
$scope.toggleDetails = function(todo) {
$scope.hideDetails = !$scope.hideDetails;
$scope.selectedTodo = todo
});
and use ng-model
<p>Id:<input type="text" ng-model="selectedTodo.id"/></p><br>
In html change parameter of toggledetail
<tr class="form-group " ng-repeat="todo in todos">
<td>
<a href ng-click="toggleDetails(todo)">
<input type="text" ng-model="todo.nume" class="form-control">
</a>
<div ng-show="Object.keys(selectedTodo).length>0">
<p>Id:<input ng-model="selectedTodo.id type="text" id="inputId"/></p><br>
<p>Nume:<input ng-model="selectedTodo.name" type="text" id="inputNume"/></p><br>
<p>Prenume:<input ng-model="selectedTodo. prenume" type="text" id="inputPrenume"/></p><br>
</div>
</div>
In controller
$scope.selectedTodo ={} //take variable
$scope.toggleDetails = function(todo) {
$scope.selectedTodo = todo;
I have to create a simple CRUD page with AngularJS.
I am able to add data with save button. Now when clicked on edit link form should get filled with the values with the row value. I am using angular's '.copy' object to get data into form.
For now text box getting valuse successfully but the select box not updating. And also want to make the select menu disable once clicked on edit link.
Below is the code:
apsApp.controller('clusterController', function ($scope ) {
var uid = 1;
$scope.clusters=[
{id:0, 'cluster':''},
];
$scope.environments = [
{name: 'DEV'},
{name: 'PROD'},
{name: 'QA'},
{name: 'Linux_Dev'}
];
$scope.selectedEnvironment = $scope.environments[0];
//add new cluster
$scope.saveNewClust = function() {
if($scope.clust.id == null) {
//if this is new cluster, add it in clusters array
$scope.clust.id = uid++;
$scope.clust.environment = $scope.selectedEnvironment.name;
console.log($scope.clust);
$scope.clusters.push($scope.clust);
}
else {
//for existing cluster, find this cluster using id and update it.
for(i in $scope.clusters) {
if($scope.clusters[i].id == $scope.clust.id) {
$scope.clusters[i] = $scope.clust;
}
}
};
//clear the add clusters form
$scope.clust = {};
};
//delete cluster
$scope.remove = function(id) {
//search cluster with given id and delete it
for(i in $scope.clusters) {
if($scope.clusters[i].id == id) {
confirm("This Cluster will get deleted permanently");
$scope.clusters.splice(i,1);
$scope.clust = {};
}
}
};
$scope.edit = function(id) {
//search cluster with given id and update it
for(i in $scope.clusters) {
if($scope.clusters[i].id == id) {
//we use angular.copy() method to create copy of original object
$scope.clust = angular.copy($scope.clusters[i]);
}
}
};
});
HTML Template is:
<div class="menuContent">
<div class="maincontent">
<div class="article">
<form>
<section>
<!-- Environment -->
<div class="col-md-6">
<label>Environment:</label>
<select ng-model="selectedEnvironment" class="form-control" ng-options="environment.name for environment in environments">
<option value='' disabled style='display:none;'>
Select Environment
</option>
</select>
</div>
<!-- cluster Name -->
<div class="col-md-6">
<label>Cluster Name:</label>
<input type="text" class="form-control" name="clusterName" placeholder="Cluster" ng-model="clust.cluster" required>
<br/>
<input type="hidden" ng-model="clust.id" />
</div>
</section>
<!-- submit button -->
<section class="col-md-12">
<button type="button" class="btn btn-default pull-right" ng-click="saveNewClust()">Save Cluster</button>
</section>
</form>
</div>
<!-- table -->
<div class="article">
<table class="table table-bordered table-striped">
<tr>
<th colspan="4">
<div class="pull-left">Cluster Info</div>
</th>
</tr>
<tr>
<th>#</th>
<th>Environment</th>
<th>Cluster</th>
<th>Edit</th>
</tr>
<tr ng-repeat="clust in clusters">
<td>{{}}</td>
<td>{{clust.environment}}</td>
<td>{{clust.cluster}}</td>
<td>
<span class="glyphicon glyphicon-edit" ></span> |
<span class="glyphicon glyphicon-trash"></span>
</td>
</tr>
</table>
</div>
</div>
</div>
I went over your code and changed a lot. Here is the new javascript part:
var app = angular.module('myApp', []);
app.controller('clusterController', function ($scope) {
var uid = 0;
$scope.clusters = [];
$scope.environments = [
{name: 'DEV'},
{name: 'PROD'},
{name: 'QA'},
{name: 'Linux_Dev'}
];
$scope.select = {};
$scope.select.selectedEnvironment = $scope.environments[0];
$scope.select.buttonLabel = 'Save Cluster';
$scope.select.showCancel = false;
//add new cluster
$scope.saveNewClust = function () {
if ($scope.select.id == undefined) {
//if this is new cluster, add it in clusters array
$scope.clusters.push({
id: uid++,
cluster: $scope.select.cluster,
environment: $scope.select.selectedEnvironment
});
} else {
//for existing cluster, find this cluster using id and update it.
$scope.clusters[$scope.select.id].cluster = $scope.select.cluster;
$scope.select.id = undefined;
$scope.select.buttonLabel = 'Save Cluster';
$scope.select.showCancel = false;
};
//clear the add clusters form
$scope.select.cluster = "";
$scope.select.selectedEnvironment = $scope.environments[0];
};
//delete cluster
$scope.remove = function (id) {
//search cluster with given id and delete it
for (i in $scope.clusters) {
if ($scope.clusters[i].id == id) {
confirm("This Cluster will get deleted permanently");
$scope.clusters.splice(i, 1);
$scope.clust = {};
}
}
};
$scope.cancelUpdate = function () {
$scope.select.buttonLabel = 'Save Cluster';
$scope.select.showCancel = false;
$scope.select.id = undefined;
$scope.select.cluster = "";
$scope.select.selectedEnvironment = $scope.environments[0];
};
});
First of all, set the var uid to 0. Don't start from 1, because the array, which you want to check starts also indexing from 0. Secondly, I added an object which persists the data for the form, where the user chooses the environment and types the name for the cluster. The object is assigned to $scope.select. There we save the preselect environment for the select box. I also save the name "Save Cancel" here, because I made it so after editing one cluster, the label of the button changes from "Save Cluster" to "Update Cluster". Like this your users will know, when exactly they edit a cluster or when they add a cluster. Furthermore, while editing a cluster, another button Cancel Update appears, so the user can also stop editing a cluster. If this button should show or not is saved in $scope.select.showCancel.
The saveNewClust function handles both routines, one for saving and one for updating. The function for editing is therefore removed. I added another function cancelUpdate, which is called in case the user cancels the action.
This is the HTML part. I just updated the form to use the new select object and the ng-click routine when the user clicks on edit. The select box is now surrounded with ng-switch. If the user edits an existing cluster, the select box is disabled.
<div ng-controller="clusterController" class="menuContent">
<div class="maincontent">
<div class="article">
<form>
<section>
<!-- Environment -->
<div class="col-md-6">
<label>Environment:</label>
<span ng-switch on="select.showCancel">
<select ng-switch-when="true" disabled ng-model="select.selectedEnvironment" class="form-control"
ng-options="environment.name for environment in environments">
<option value='' disabled style='display:none;'>
Select Environment
</option>
</select>
<select ng-switch-default ng-model="select.selectedEnvironment" class="form-control"
ng-options="environment.name for environment in environments">
<option value='' disabled style='display:none;'>
Select Environment
</option>
</select>
</span>
</div>
<!-- cluster Name -->
<div class="col-md-6">
<label>Cluster Name:</label>
<input type="text" class="form-control" name="clusterName" placeholder="Cluster"
ng-model="select.cluster" required>
<br/>
<input type="hidden" ng-model="clust.id"/>
</div>
</section>
<!-- submit button -->
<section class="col-md-12">
<button type="button" class="btn btn-default pull-right" ng-click="saveNewClust()">{{select.buttonLabel}}
</button>
<button ng-show="select.showCancel" type="button" class="btn btn-default pull-right" ng-click="cancelUpdate()">Cancel update
</button>
</section>
</form>
</div>
<!-- table -->
<div class="article">
<table class="table table-bordered table-striped">
<tr>
<th colspan="4">
<div class="pull-left">Cluster Info</div>
</th>
</tr>
<tr>
<th>#</th>
<th>Environment</th>
<th>Cluster</th>
<th>Edit</th>
</tr>
<tr ng-repeat="clust in clusters">
<td>{{}}</td>
<td>{{clust.environment.name}}</td>
<td>{{clust.cluster}}</td>
<td>
<span class="glyphicon glyphicon-edit"></span>Edit
|
<a href="" ng-click="remove(clust.id)" title="Delete"><span
class="glyphicon glyphicon-trash"></span>Delete</a>
</td>
</tr>
</table>
</div>
</div>
</div>
Here is the jsfiddle for testing: http://jsfiddle.net/hv7Pb/
So I'm new to AngularJS and I'm trying to build a very simple list app, where I can create an ng-repeat item list and then push a selected item into another ng-repeat list. Although my problem seems to be very simple I wasn't able to find a proper solution yet.
So here's the simplified markup:
<body ng-app="MyApp">
<div id="MyApp" ng-controller="mainController">
<div id="AddItem">
<h3>Add Item</h3>
<input value="1" type="number" placeholder="1" ng-model="itemAmount">
<input value="" type="text" placeholder="Name of Item" ng-model="itemName">
<br/>
<button ng-click="addItem()">Add to list</button>
</div>
<!-- begin: LIST OF CHECKED ITEMS -->
<div id="CheckedList">
<h3>Checked Items: {{getTotalCheckedItems()}}</h3>
<h4>Checked:</h4>
<table>
<tr ng-repeat="item in checked" class="item-checked">
<td><b>amount:</b> {{item.amount}} -</td>
<td><b>name:</b> {{item.name}} -</td>
<td>
<i>this item is checked!</i>
</td>
</tr>
</table>
</div>
<!-- end: LIST OF CHECKED ITEMS -->
<!-- begin: LIST OF UNCHECKED ITEMS -->
<div id="UncheckedList">
<h3>Unchecked Items: {{getTotalItems()}}</h3>
<h4>Unchecked:</h4>
<table>
<tr ng-repeat="item in items" class="item-unchecked">
<td><b>amount:</b> {{item.amount}} -</td>
<td><b>name:</b> {{item.name}} -</td>
<td>
<button ng-click="toggleChecked($index)">check item</button>
</td>
</tr>
</table>
</div>
<!-- end: LIST OF ITEMS -->
</div>
</body>
And here goes my AngularJS Script:
var app = angular.module("MyApp", []);
app.controller("mainController",
function ($scope) {
// Item List Arrays
$scope.items = [];
$scope.checked = [];
// Add a Item to the list
$scope.addItem = function () {
$scope.items.push({
amount: $scope.itemAmount,
name: $scope.itemName
});
// Clear input fields after push
$scope.itemAmount = "";
$scope.itemName = "";
};
// Add Item to Checked List and delete from Unchecked List
$scope.toggleChecked = function (item, index) {
$scope.checked.push(item);
$scope.items.splice(index, 1);
};
// Get Total Items
$scope.getTotalItems = function () {
return $scope.items.length;
};
// Get Total Checked Items
$scope.getTotalCheckedItems = function () {
return $scope.checked.length;
};
});
So when I click the button, my toggleChecked() function triggers and it actually pushes something into my checked list. However, it seems to be just an empty object. The function can't get the actual item that I want to push.
What am I doing wrong here?
NOTE: Checking items via click on a button is intended. I don't want to use checkboxes in this case.
You can see the working model here: http://jsfiddle.net/7n8NR/1/
Cheers,
Norman
change your method to:
$scope.toggleChecked = function (index) {
$scope.checked.push($scope.items[index]);
$scope.items.splice(index, 1);
};
Working Demo
You'd be much better off using the same array with both lists, and creating angular filters to achieve your goal.
http://docs.angularjs.org/guide/dev_guide.templates.filters.creating_filters
Rough, untested code follows:
appModule.filter('checked', function() {
return function(input, checked) {
if(!input)return input;
var output = []
for (i in input){
var item = input[i];
if(item.checked == checked)output.push(item);
}
return output
}
});
and the view (i added an "uncheck" button too)
<div id="AddItem">
<h3>Add Item</h3>
<input value="1" type="number" placeholder="1" ng-model="itemAmount">
<input value="" type="text" placeholder="Name of Item" ng-model="itemName">
<br/>
<button ng-click="addItem()">Add to list</button>
</div>
<!-- begin: LIST OF CHECKED ITEMS -->
<div id="CheckedList">
<h3>Checked Items: {{getTotalCheckedItems()}}</h3>
<h4>Checked:</h4>
<table>
<tr ng-repeat="item in items | checked:true" class="item-checked">
<td><b>amount:</b> {{item.amount}} -</td>
<td><b>name:</b> {{item.name}} -</td>
<td>
<i>this item is checked!</i>
<button ng-click="item.checked = false">uncheck item</button>
</td>
</tr>
</table>
</div>
<!-- end: LIST OF CHECKED ITEMS -->
<!-- begin: LIST OF UNCHECKED ITEMS -->
<div id="UncheckedList">
<h3>Unchecked Items: {{getTotalItems()}}</h3>
<h4>Unchecked:</h4>
<table>
<tr ng-repeat="item in items | checked:false" class="item-unchecked">
<td><b>amount:</b> {{item.amount}} -</td>
<td><b>name:</b> {{item.name}} -</td>
<td>
<button ng-click="item.checked = true">check item</button>
</td>
</tr>
</table>
</div>
<!-- end: LIST OF ITEMS -->
Then you dont need the toggle methods etc in your controller
Try this one also...
<!DOCTYPE html>
<html>
<body>
<p>Click the button to join two arrays.</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<p id="demo1"></p>
<script>
function myFunction() {
var hege = [{
1: "Cecilie",
2: "Lone"
}];
var stale = [{
1: "Emil",
2: "Tobias"
}];
var hege = hege.concat(stale);
document.getElementById("demo1").innerHTML = hege;
document.getElementById("demo").innerHTML = stale;
}
</script>
</body>
</html>