http://jsfiddle.net/u0jzkye1/
<div ng-app ng-controller="MyCtrl">
<ul>
<li ng-repeat="item in items">{{item.name}}</li>
</ul>
<button type="submit" ng-click="send()">
Send
</button>
</div>
When the button is not within ng-repeat, how can I pass my item's id into ng-click function?
Well items is already on $scope as you're using it in your ng-repeat. So you should simply be able to ng-click="send(items)"
var items = [{
id: 1,
name: "one"
}, {
id: 2,
name: "two"
}];
function MyCtrl($scope) {
$scope.items = items;
$scope.send = function() {
//get items' id
$scope.items.forEach(function(item){
alert(item.id);
}, this);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="MyCtrl">
<ul>
<li ng-repeat="item in items">{{item.name}}</li>
</ul>
<button type="submit" ng-click="send()">
Send
</button>
</div>
Related
im struggling with iterating over arrays in arrays. I need to create buttonlike vertical menu and cant get it work.
angular.module('NavigationApp',[]).controller('NavigationController', function($scope) {
$scope.items = [
'Home',
'Orders':
{
orders:['Orders', 'Open', 'Closed', 'New', 'Forgotten']
},
'Users',
'Resources',
'Settings',
'Help'
];
$scope.activeMenu = $scope.items[0];
$scope.setActive = function(item) {
$scope.activeMenu = item;
};
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
</head>
<body ng-app="NavigationApp">
<div class="col-md-3">
<div ng-controller="NavigationController">
<input type="text" placeholder="Search" ng-model="filterQuery" />
<ul class="list-group">
<li ng-click="setActive(item)" ng-class="{active: activeMenu === item}" class="btn btn-lg list-group-item" ng-repeat="item in items | filter:filterQuery">{{ item }}
</li>
</ul>
</div>
</div>
<script src="js/MainController.js"></script>
</body>
</html>
What i need to do is display array of items and while Orders item is active expand it with elements given in other array. To be honest i just dont know how to make it.
You are trying to ng-repeat over a heterogeneus array. i.e. it's elements are not all of the same type. The implementation logic needs to change here.
One thing you can do if your data structure is not flexible, is to use a typeof item === 'object' to filter out the object from the strings, or conversely check for typeof string
Here's a quick, basic example of what you could use:
$scope.items = [{
name: 'Home'
}, {
name: 'Orders',
dropdown: [{
name: 'Orders'
}]
},{
name: 'Users'
},
...
];
<li ng-repeat="item in items | filter:filterQuery" class="btn btn-lg list-group-item dropdown" ng-class="{active: activeMenu === item}" ng-click="setActive(item)">
<a aria-expanded="false" aria-haspopup="true" role="button" data-toggle="dropdown" class="dropdown-toggle" href="#">
{{ item.name }} <span class="caret" ng-if="item.dropdown"></span>
</a>
<ul ng-if="item.dropdown" class="dropdown-menu">
<li ng-repeat="dItem in item.dropdown">
{{dItem.name}}
</li>
</ul>
</li>
I'd suggest having another indepth look at https://docs.angularjs.org/api/ng/directive/ngRepeat to fully understand the structure required by the directive.
angular.module('NavigationApp',[]).controller('NavigationController', function($scope) {
$scope.items = {
main:['Home','Orders','Users','Resources','Settings','Help'],
sub:['Open','Closed','New','Forgotten']
};
$scope.activeMenu = $scope.items[0];
$scope.setActive = function(item) {
$scope.activeMenu = item;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
</head>
<body ng-app="NavigationApp">
<div class="col-md-3">
<div ng-controller="NavigationController">
<input type="text" placeholder="Search" ng-model="filterQuery" />
<ul class="list-group">
<li ng-click="setActive(item)" ng-class="{active: activeMenu === item}" class="btn btn-lg list-group-item" ng-repeat="item in items.main | filter:filterQuery">{{ item }}
<ul>
<li class="btn btn-lg list-group-item" ng-repeat="it in items.sub" ng-if="activeMenu === 'Orders'">{{it}}</li>
</ul>
</li>
</ul>
</div>
</div>
<script src="js/MainController.js"></script>
</body>
</html>
This is closer to what i want to achieve. But i dont know how to apply this nested UL to only one Li from parent list.
this filter work correctly
INPUT :
['Home',{ 'Orders':{orders:['Orders', 'Open', 'Closed', 'New', 'Forgotten']}},'Users','Resources','Settings','Help']
OUTPUT :
["Home", "Orders", "Open", "Closed", "New", "Forgotten", "Users", "Resources", "Settings", "Help"]
app.filter('customfilter', function () {
return function (data) {
function clean(item)
{
var result = [] ;
// check if type is array
if(Array.isArray(item)){
// parse array
item.forEach(function(i){
result = result.concat(clean(i));
})
}// check if type is opject
else if(typeof item =="object"){
// parse opject
Object.keys(item).map(function (key) {
result = result.concat(clean(item[key]));
});
}else{
result= [item]
}
return result ;
}
return clean(data) ;
}
})
I believe there are so many ways to answer this question,although I've made a sample plunker for your problem.Below is how your
HTML will look like
<body ng-app="NavigationApp">
<div class="col-md-3">
<div ng-controller="NavigationController">
<input type="text" placeholder="Search" ng-model="filterQuery" />
<ul class="list-group">
<li ng-click="setActive(item)" ng-class="{active: activeMenu === item}" class="btn btn-lg list-group-item" ng-repeat="item in items | filter:filterQuery">
<a href="#">
<p ng-hide="item.dropdown"> {{ item.name }}</p>
<p ng-show="item.dropdown" ng-repeat="values in item.dropdown"> {{ values }}</p>
</a>
</li>
</ul>
</div>
</div>
</body>
JS look like
angular.module('NavigationApp', []).controller('NavigationController', function($scope) {
var orderItemsObj = {
orders: ['Orders', 'Open', 'Closed', 'New', 'Forgotten']
};
$scope.items = [{
name: 'Home'
}, {
name: 'Orders',
dropdown: ['Orders', 'Open', 'Closed', 'New', 'Forgotten']
}, {
name: 'Users'
}, ];
$scope.activeMenu = $scope.items[0];
$scope.setActive = function(item) {
$scope.activeMenu = item;
};
});
The array is structured like so
$scope.structure = {
sections: [{
id:0,
sectionItems: []
},{
id:1,
sectionItems: []
},{
id:2,
sectionItems: []
}]
};
I have a nested ng-repeat so I can show items within sectionItems[]
(Inside should be objects and one of the keys is Name - not relevant)
<div ng-repeat="sections in structure.sections" class="col-md-12">
<div class="panel panel-info">
<ul class="screenW-section">
<li class="col-xs-6" ng-repeat="item in sections.sectionItems"
ng-click="item.splice($index, 1)">
{{item.Name}}
</li>
</ul>
</div> </div>
I want to be able to remove items on click but the
ng-click="item.splice($index, 1)
Is not working no matter how I format it.
try this:
var app = angular.module("testApp", []);
app.controller('testCtrl', function($scope){
$scope.structure = {
sections: [{
id:0,
sectionItems: ['1','2','3']
},{
id:1,
sectionItems: ['11','21','32']
},{
id:2,
sectionItems: ['12','22','32']
}]
};
$scope.remove = function(sectionItems,index){
sectionItems.splice(index, 1);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="testApp" ng-controller="testCtrl">
<div ng-repeat="sections in structure.sections" class="col-md-12">
<div class="panel panel-info">
<ul class="screenW-section">
<li class="col-xs-6" ng-repeat="item in sections.sectionItems"
ng-click="remove(sections.sectionItems,$index)">
{{item}}
</li>
</ul>
</div> </div>
</div>
To remove an item you need to remove it from the array.
So, for example, you could do
ng-click="remove(sections.sectionItems, $index)"
in the view, and
$scope.remove = function(array, index) {
array.splice(index, 1);
}
in the controller...
You're calling splice on the item and not the array
ng-click="sections.sectionItems.splice($index, 1)"
I want to use angular-drag-and-drop-lists with my own grid template to WYSIWYG editor. How to build my own HTML template without ng-repeat so it will be able to drop items in any predefined column and store information in $scope in which column item has been dropped?
I want to store dropped items in columns array:
.controller('DragDropGrid', ['$scope',
function($scope) {
$scope.layouts = {
selected: null,
templates: [
{name: "Plugin", type: "item", id: 2},
],
columns: [],
oldaproachcolumns: [
"A": [
],
"B": [
]
}
]
};
}
]);
This is currently not a working template. On drop it throws the error "undefined is not an object (evaluating 'targetArray.splice')":
<div ng-include="'grid.html'"></div>
<script type="text/ng-template" id="grid.html">
<div class="col-md-12 dropzone box box-yellow">
<div class="row template-grid" dnd-list="list">
<div class="col-xs-12 col-md-8" ng-repeat="item in list" dnd-draggable="item" ng-include="item.type + '.html'">Header</div>
<div class="col-xs-6 col-md-4">News</div>
</div>
</div>
</script>
<script type="text/ng-template" id="item.html">
<div class="item">Plugin {{item.id}}</div>
</script>
This is the standard working aproach:
<div class="row">
<div ng-repeat="(zone, list) in layouts.oldaproachcolumns" class="col-md-3">
<div class="dropzone box box-yellow">
<h3>{{zone}}</h3>
<div ng-include="'list.html'"></div>
</div>
</div>
</div>
<script type="text/ng-template" id="list.html">
<ul dnd-list="list">
<li ng-repeat="item in list" dnd-draggable="item" dnd-effect-allowed="move" dnd-moved="list.splice($index, 1)" dnd-selected="layouts.selected = item" ng-class="{selected: layouts.selected === item}" ng-include="item.type + '.html'">
</li>
</ul>
</script>
Based on this example: demo
How to build my own HTML template without ng-repeat
Use $templateCache and a for loop as an alternative:
var app = angular.module('foo', []);
function bop(model, data)
{
return data ? model : 'foo';
}
function baz()
{
return bop;
}
function foo($templateCache)
{
var i = 0, len = 5, bar = "";
for (i; i < len; i++)
{
bar = bar.concat("<li>",i,"<p ng-include=\u0022'foo'\u0022></p></li>");
}
$templateCache.put('listContent', bar);
}
angular.module('foo').filter('baz', baz);
app.run(foo);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="foo">
<script type="text/ng-template" id="foo">
<span>hi</span>
</script>
<input ng-model="dude">
<ul ng-include="'listContent' | baz:dude"></ul>
</div>
References
AngularJS: API: $templateCache
AngularJS: Is there a better way to achieve this than the one specified?
I have a list of checkboxes and need to count checked checkboxes.
<div id="list" ng-controller = "listContr as ilist">
<ul>
<li ng-repeat = "item in ilist.items| filter: searchText">
<input type = "checkbox" ng-model="item.done" id="ch">
</li>
</ul>
</div>
In my project I try to get this value using another controller. It's also complicated because this value should be dynamically changed.
Please see here http://jsbin.com/guzaco/2/edit
You can use angular service to share data between controllers.
JS:
var app = angular.module('app', []);
app.service("dataService", function(){
var _items = [
{id:1, done:false},
{id:3, done:true},
{id:2, done:false}
];
return {
items:_items,
};
});
app.controller('firstCtrl', function($scope,$filter,dataService){
$scope.items = dataService.items;
$scope.$watch('items', function(){
$scope.count = ($filter('filter')($scope.items, {done:true})).length;
}, true);
});
app.controller('listContr', function($scope,dataService){
$scope.data = dataService;
});
HTML:
<body ng-app="app">
<div ng-controller="firstCtrl">
<p>First Controller</p>
Count: {{count}}
</div>
<div id="list" ng-controller = "listContr">
<p>List Controller</p>
<ul>
<li ng-repeat = "item in data.items| filter: searchText">
<input type = "checkbox" ng-model="item.done" id="ch">
</li>
</ul>
</div>
</body>
<script>
$(document).ready(function()
{
//Method 1:
alert($('.checkbox_class_here :checked').size());
//Method 2:
alert($('input[name=checkbox_name]').attr('checked'));
//Method: 3
alert($(":checkbox:checked").length);
});
</script>
I have put all necessary files into a single file. I want to push item into array when the user clicks on a button. Here is the content:
When I click on the button, nothing happens. Also the data is not repeated/looped and {{}} is shown in angular which means there is a problem.
<script type="text/javascript" src="angular.js" ></script>
<div data-ng-app="App">
<div data-ng-controller="MyController">
<ul data-ng-repeat="one in names">
<li>{{ one.first }}</li>
</ul>
</div>
</div>
<input type="text" data-ng-model="Namer.name"/>
<input type="submit" data-ng-click="AddName()"/>
<script type="text/javascript">
var App = angular.module("App", []);
App.controller("MyController", function($scope){
$scope.names = [
{ first : "Thomas"},
{ first : "Geferson"},
{ first : "Jenny"},
{ first : "Maria"},
];
$scope.AddName = function(){
$scope.names.push({
name : $scope.Namer.name;
});
};
});
</script>
Working DEMO
var App = angular.module("App", []);
App.controller("MyController", function ($scope) {
$scope.names = [{
first: "Thomas"
}, {
first: "Geferson"
}, {
first: "Jenny"
}, {
first: "Maria"
}];
$scope.AddName = function () {
$scope.names.push({
first: $scope.Namer.name
});
};
});
You need to move your data-ng-click inside Controller.Also you had some syntax issues.That is also i fixed (To work with IE ALSO)
<div data-ng-app="App">
<div data-ng-controller="MyController">
<ul data-ng-repeat="one in names">
<li>{{ one.first }}</li>
</ul>
<input type="text" data-ng-model="Namer.name" />
<input type="submit" data-ng-click="AddName()" />
</div>
</div>
Move your inputs to inside your MyController so that it executes code in the scope created by the controller:
<div data-ng-app="App">
<div data-ng-controller="MyController">
<ul data-ng-repeat="one in names">
<li>{{ one.first }}</li>
</ul>
<input type="text" data-ng-model="Namer.name"/>
<input type="submit" data-ng-click="AddName()"/>
</div>
</div>
Another mistake is that you need to change name to first to match with your existing object
$scope.AddName = function(){
$scope.names.push({
first : $scope.Namer.name //change to first and remove the ;
});
};
DEMO