I'm new to AngularJS and can't find any suitable answer for this. My app currently consists of a list of items displayed via Angular. There is also a label which displays the name of the currently selected item, and an input box which allows the name of the currently selected item to be modified.
What I cannot figure out is how to simultaneously:
Allow the selection of an item, which triggers the update of the label and the input box text to display the name of the newly selected item
Allow editing of the name in the input box which triggers the update of the label displaying the currently displayed item name
Edits to the name should be reflected in the original model item
At the moment, i'm trying to keep track of which item is current via a flag against the item and this isn't doing what I want. Ideally I would replace currentItem in the below with a direct reference to the item in items with isCurrent=true.
Current item name label:
`<div id="CurrentItem" data-ng-model="currentItem">{{currentItem.name}}</div>`
Current item name input box:
`<input id="ItemName" type="text" data-ng-model="currentItem" value="{{currentItem.name}}" />`
Display all items:
<div data-ng-repeat="item in items" data-ng-click="changeItem(item)">`
<img src="images/ItemIcon.png">
<div>{{item.name}}</div>
Controller:
var CoreAppController = function($scope, $location) {
$scope.changeItem = function(item) {
var length = $scope.items.length;
while(length-- ) {
$scope.items[length].isCurrent = false;
}
$scope.currentItem = item;
$scope.items.indexOf(item).isCurrent = false;
}
$scope.createItem = function(name, layout) {
$scope.items.push({ id: $scope.items.length + 1,
name: name,
isCurrent: false
});
}
// Initialisation
$scope.items = [];
$scope.createItem("Item 1");
$scope.createItem("Item 2");
$scope.items[0].isCurrent = true;
$scope.currentItem = $scope.items[0];
}
Any advice appreciated!
I'm not sure about your current code, but here is a mock up that does what it appears you're requesting.
The JS
app.controller('MainCtrl', function($scope) {
$scope.items = [
{ name: 'foo' },
{ name: 'bar' },
{ name: 'test' }
];
$scope.editing = null;
$scope.editItem = function(item) {
$scope.editing = item;
}
});
and the markup
<body ng-controller="MainCtrl">
<ul>
<li ng-repeat="item in items">
{{item.name}}
<a ng-click="editItem(item);">edit</a>
</li>
</ul>
<div ng-show="editing">
<input type="text" ng-model="editing.name"/>
<span>{{editing.name}}</span>
</div>
</body>
Hopefully that helps. If you need more of a description, let me know.
Related
I would like to store the value of a selection from a dropdown in AngularJS.
I am able to replicate the new selection on UI but not in console.
<div ng-controller="MyCtrl">
<div>
Fruit List:
<select id="fruitsList"
ng-model="cart"
ng-change="getSelectedLocation()"
ng-options="state for state in shelf"></select>
<br/>
<tt>Fruit selected: {{cart}}</tt>
</div>
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.cart = "";
$scope.shelf = ['Banana', 'Apple', 'Pineapple', 'Blueberry'];
$scope.getSelectedLocation = function() {
console.log($scope.cart);
}
$scope.printSelectedValue = function() {
if ($scope.cart == 'Banana') {
console.log("Its a banana")
} else if ($scope.cart == "Apple") {
console.log("Its an apple")
} else {
console.log("Its neither a banana nor an apple")
}
}
});
Any idea on how to achieve that?
jsfiddle link
You're printing the cart once, when the controller is instanciated. At that time, the user hasn't had the chance to select anything yet.
If you want to print the selection every time it changes, use ng-change (you're already using it, BTW):
ng-change="printSelection()"
and in the controller:
$scope.printSelection = function() {
console.log($scope.cart);
};
I've got two scope objects
$scope.selectedItems = [1,3]
$scope.items = [{'id':'1','name':'apple'},{'id':'2','name':'banana'},{'id':'3','name':'grapes'}]
In my template I want to use ng-repeat for $scope.selectedItems, but show item names. Is it possible?
Smth. like
<span ng-repeat="selItem in selectedItems track by $index">{{ items.name | items.id == selItem }}</span>
You have few of issues, First is that your ids are string but your stored array of selected items are numbers. My solution tries to accommodate that.
You need to create a third scope property that dynamically calculates the items that have the same id as your selected items ids and returns them.
$scope.selectedItemIds = [1,3]
$scope.items = [{'id':'1','name':'apple'},{'id':'2','name':'banana'},{'id':'3','name':'grapes'}];
$scope.selectedItems = function(){
var _selectedItems = [];
angular.forEach($scope.items, function(item){
if ($scope.selectedItemIds.indexOf(Number(item.id)) != -1){
_selectedItems.push(item);
}
});
return _selectedItems;
};
Now you can use that function in your ng-repeat iterator to access the selected items on the view:
<ul>
<li ng-repeat="item in selectedItems()">{{ item.name }}</li>
</ul>
Here is a working fiddle
You can try it by custom filter:
In controller:
$scope.selectedItems = ['1','3'];
$scope.items = [{'id':'1','name':'apple'},{'id':'2','name':'banana'}, {'id':'3','name':'grapes'}];
$scope.getselectedItem= function(item) {
if($scope.selectedItems.indexOf(item.id)!==-1) {
return item;
}
else {
return null;
}
};
In Html:
<p ng-repeat="item in items | filter: getselectedItem">{{item.name}}</p>
I have two list (List 1 and List 2) of check box in which three items
available in both list. My problem is when I checked on list 1 item
then list 2 item also checked not sure why. I need to stop this. My
requirement is when I checked list 1 item then it does not affect
List 2 item. Please help
Fiddle Here
VIEW
<div ng-app="checkbox" ng-controller="homeCtrl">
<div ng-repeat="item in list">
<input type="checkbox" ng-model="item.checked"
ng-click="fnChangeAssetType1(item)" />
<label>{{item.value}}</label>
</div>
<br/><br/>
New List<br/><br/>
<div ng-repeat="items in lists">
<input type="checkbox" ng-model="items.checked"
ng-click="fnChangeAssetType(items)" />
<label>{{items.value}}</label>
</div>
</div>
JS
var app = angular.module('checkbox', []);
app.controller('homeCtrl', function($scope) {
var list = [{
"id": 1,
"value": "apple",
}, {
"id": 3,
"value": "orange",
}, {
"id": 5,
"value": "pear"
}];
$scope.list=list;
$scope.lists=list;
$scope.fnChangeAssetType = function (items) {
angular.forEach($scope.lists, function (item) {
item.checked = false;
});
items.checked = true;
};
$scope.fnChangeAssetType1 = function (items) {
angular.forEach($scope.list, function (item) {
item.checked = false;
});
items.checked = true;
};
});
This is because your $scope.list & $scope.lists both are pointing to same array in the memory because of array (list) is a reference type. what u need to do is create a separate array for $scope.lists as below.
you need to use angular.copy()
$scope.list=list;
$scope.lists= angular.copy(list); // this will create a deep copy of list array and store it in another memory slot, //refer the angular.copy doc
here is the updated fiddle
I'm implementing simple pictures list.
here's my code. I have 2 questions:
1. I want to make a single choice whenever the user click an image. Whenever he choose one picture it will clear the other choice. how can I do that?
2. Instead of border I would like to use an icon such as fa-check (http://fontawesome.io/icon/check/). How can I combine it in the css?
Thanks!
css file
.selected {
border:2px solid red;
}
js file
$scope.items = [
{imageUrl: '/app/img/item1.jpg'},
{imageUrl: '/app/img/item2.jpg'}];
$scope.toggle = function (item) {
item.selected = !item.selected;
};
html file
<div class="category rating-type">
<h5>items list</h5>
<div class="pics-continer">
<ul>
<li ng-repeat="item in items" ng-click="toggle(item)" ng-class="{'selected':item.selected}">
<div style="background-image: url({{item.imageUrl}});height:36px; width:40px;display:inline-block"></div>
</li>
</ul>
</div>
Change your taggle method as follows to have a single select image list.
$scope.toggle = function (item) {
$scope.selectedImage = item.imageUrl;
};
And change the view as
<li ng-repeat="item in items" ng-click="toggle(item)" ng-class="{'selected':item.imageUrl == selectedImage}">
<img src="{{item.imageUrl}}" style="height:36px; width:40px;"/>
</li>
So only one image can be selected at the same time.
For using an icon instead of border you can set the icon as background image.
the following link are usefull
CSS background-position Property
I think it is best put as much code as possible in the controller - this is easier to test. So: the html snippet:
<li ng-repeat="item in items" ng-click="selectItem(item)"
ng-class="{'fa fa-check':isSelected(item)}">
<div style="background-image: url({{item.imageUrl}});
height:36px; width:40px;display:inline-block"></div>
</li>
the controller:
controller('TestController', function($scope){
$scope.items = [
{imageUrl: '/app/img/item1.jpg'},
{imageUrl: '/app/img/item2.jpg'}
];
$scope.selectedItem = null;
$scope.selectItem = function(item){
$scope.selectedItem = item;
};
$scope.isSelected = function(item){
if($scope.selectedItem===null){
return false;
}
return item.imageUrl === $scope.selectedItem.imageUrl;
};
})
how to setup fontawesome is documented here: http://fontawesome.io/get-started/ After that you can use the css class names provided by fontawesome. Also included in the example above.
$scope.items = [
{imageUrl: '/app/img/item1.jpg'},
{imageUrl: '/app/img/item2.jpg'}];
$scope.toggle = function (item) {
item.selected = !item.selected;
};
that item is a index for items, but you didn't set selected in your items array . So item.selected it's threw undefined error
Please try this way
$scope.items = [
{imageUrl: '/app/img/item1.jpg',selected:true},
{imageUrl: '/app/img/item2.jpg',selected:false}];
I want to save and load a checkbox list using binding in angularjs with a node backend. This SO question (How do I bind to list of checkbox values with AngularJS?) answers how I can load the check box from a static javascript object but how can I save the checkbox values after the user selects them?
I want to save the checkbox values in a single field but how can I tell angular to bind the checkbox values into a single field defined in a model to my mongodb? I cant just use ng-model as there are multiple checkboxes.
Needless to say that I am new to angular so any help here is greatly appreciated ...
Thanks for any help you can provide.
kseudo
Just add ng-model to your checkbox. By this way you can update model in controller on any checkbox state change.
Here is example:
HTML
<div ng-controller="Ctrl">
<label ng-repeat="fruit in fruits">
<input
type="checkbox"
name="fruit.name"
ng-model="fruit.value"
> {{fruit.name}}
</label>
<pre>{{fruits| json}}</pre>
</div>
JS
var app = angular.module('app', []);
function Ctrl($scope) {
$scope.fruits = [{
name: 'apple',
value: false
}, {
name: 'orange',
value: false
}, {
name: 'pear',
value: false
}, {
name: 'naartjie',
value: false
}];
}
Demo Fiddle
[EDIT]
BTW we can make the copy by using angular.copy() method. When we press button, the new copy of fruits model will be created (and you should send it to server as json). Old model fruits will stay the same:
$scope.fruitsCopy = [];
$scope.init = function(){
$scope.fruitsCopy = angular.copy($scope.fruits );
}
To convert data to JSon I would use:
var jsonData = JSON.stringify($scope.fruitsCopy);
Demo2 Fiddle
Let's say you defined your model as such:
function Ctrl($scope) {
$scope.items = [{
name: 'A',
checked: false
}, {
name: 'B',
checked: false
}, {
name: 'C',
checked: false
}, {
name: 'D',
checked: false
}];
}
And created a view for the model:
<ul>
<li ng-repeat="item in items">
<label>
<input type="checkbox" ng-model="item.checked">
{{item.name}}
</label>
</li>
</ul>
<button ng-click="save()">save</button>
Next you have to define save function:
$scope.save = function() {
//angular.toJson converts array to string, something like
// '[{"name":"A","checked":false},{"name":"B","checked":true},...]'
var json = angular.toJson($scope.items);
//Service is angular service for your model that makes http requests to your backend
Service.save(json).then(function(){
//here you can notify user that data is persisted
}, function() {
//here you can notify user that there was a problem with request
});
}
And a simple model service:
.service('Service', function($http) {
return new function() {
this.save = function(data) {
return $http.post('url/to/backend', data);
}
}
});