Angular show hide toggle on ng-repeat - angularjs

I have this ngRepeat. I want to create some sort of toggle, so that when the user clicks on the button, the input shows, however, I want all other shown inputs to hide (if they are already visible).
<ul>
<li ng-repeat="(key, value) in jewel">
<span ng-show="!showMe">text here</span>
<input ng-show="showMe">
<button ng-click="showMe = true"></button>
</li>
</ul>
Hope this makes sense.

ng-repeat has isolated scope, that is why to influence all other inputs you need to track their visibility via variable from parent scope. I've prepeared a fiddle with example: http://jsfiddle.net/ancvgc1b/
angular
.module('myApp', ['ui.bootstrap'])
.controller('ExampleController', function($scope){
$scope.jewel = {
key1: 'Foo',
key2: 'Bar'
};
$scope.visible = { key: 'key1' };
$scope.setVisible = function(key) {
$scope.visible.key = key;
}
});
<body ng-app="myApp">
<div ng-controller='ExampleController'>
<ul>
<li ng-repeat="(key, value) in jewel">
<span ng-show="!(visible.key == key)">Text value</span>
<input ng-show="visible.key == key">
<button ng-click="setVisible(key)">show input</button>
</li>
</ul>
</div>
</body>

Quick fix:
<ul ng-init="active={}">
<li ng-repeat="(key, value) in jewel">
<span ng-show="!($index==active.index)">text here</span>
<input ng-show="$index==active.index">
<button ng-click="active.index = $index"></button>
</li>
</ul>
If you are using controllerAs, it leads to much cleaner code as follows:
(vm is your alias to controller)
<ul>
<li ng-repeat="(key, value) in jewel">
<span ng-show="!($index==vm.activeIndex)">text here</span>
<input ng-show="$index==vm.activeIndex">
<button ng-click="vm.activeIndex = $index"></button>
</li>
</ul>

Try this :
var app = angular.module('myApp', []);
app.controller('MyCtrl',function($scope) {
$scope.people = [
{
id: 1,
name: "Alpha",
age: "24",
clicked : false
},
{
id: 2,
name: "Beta",
age: "25",
clicked : false
}
];
$scope.showInput = function(person,index) {
person.input = true;
$scope.index = index;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<ul>
<li ng-repeat="person in people">
<span ng-show="(!person.input && (index != $index))">text here</span>
<input ng-show="(person.input && (index == $index))">
<button ng-click="showInput(person,$index)">Show Input</button>
</li>
</ul>
</div>

Related

how to implement show more in <li> with angularjs ng-repeat directive?

How Do I hide the list data if the list is greater than 3? and a show more button that will show the whole list when it's clicked?
Here is my current code, i do not know how to implement the show more when the ng-repeat directive is inside the li tag.
<ul>
<li ng-repeat="data in datas">
<div>data</div>
</li>
</ul>
How about this?
var app = angular.module("App", []);
app.controller("Ctrl", [function () {
var ctrl = this;
ctrl.items = ["Item1", "Item2", "Item3", "Item4", "Item5", "item6"]
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="App" ng-controller="Ctrl as ctrl">
<ul ng-init="limit = 3">
<li ng-repeat="item in ctrl.items | limitTo: limit as results">{{item}}</li>
</ul>
<button ng-hide="results.length === ctrl.items.length"
ng-click="limit = limit +2">show more...</button>
</div>

How to use controller as syntax in the following scenario

controller as syntax problem
I am a newbie to angular, so please forgive me if i'm wrong. I have a problem where a service is used for certain operation. In this case, adding books to cart.
I have followed the recommended way using controller as syntax instead of $scope. But in kart-list.html, i'm not able to access kart details, since this operation is done by BookListCtrl.
app.js
var app = angular.module("app", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/books", {
templateUrl: "partials/book-list.html",
controller: "BookListCtrl",
controllerAs: 'booklist'
})
.when("/kart", {
templateUrl: "partials/kart-list.html",
controller: "KartListCtrl",
})
.otherwise({
redirectTo: "/books"
});
});
app.factory("kartService", function() {
var kart = [];
return {
getKart: function() {
return kart;
},
addToKart: function(book) {
kart.push(book);
},
buy: function(book) {
alert("Thanks for buying: ", book.name);
}
};
});
app.factory("bookService", function() {
var books = ['some data'];
return {
getBooks: function() {
return books;
},
addToKart: function(book) {
}
}
});
app.controller("KartListCtrl", function(kartService) {
var self = this;
self.kart = kartService.getKart();
self.buy = function(book) {
kartService.buy(book);
};
});
app.controller("HeaderCtrl", function() {
var self = this;
self.appDetails = {};
self.appDetails.title = "BooKart";
self.appDetails.tagline = "We have collection of 1 Million books";
});
app.controller("BookListCtrl", function(bookService, kartService) {
var self = this;
self.books = bookService.getBooks();
self.addToKart = function(book) {
kartService.addToKart(book);
};
});
book-list.html
<div id="bookListWrapper">
<form role="form">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search here..." />
</div>
</form>
<ul class="list-unstyled">
<li class="book" ng-repeat="book in booklist.books" style="background: white url('imgs/{{book.imgUrl}}') no-repeat">
<div class="book-details clearfix">
<h3>{{book.name}}</h3>
<p>{{book.price}}</p>
<ul class="list-unstyled list-inline">
<li>Rating: {{book.rating}}</li>
<li>Binding: {{book.binding}}</li>
<li>Publisher: {{book.publisher}}</li>
<li>Released: {{book.releaseDate}}</li>
</ul>
<p>{{book.details}}</p>
<button class="btn btn-info pull-right" ng-click="addToKart(book)">Add to Kart</button>
</div>
</li>
</ul>
</div>
kart-view.html
<div id="bookListWrapper">
<p>Please click on buy button to buy the book.</p>
<ul class="list-unstyled">
<li class="book" ng-repeat="book in kart" style="background: white url('imgs/{{book.imgUrl}}') no-repeat">
<div class="book-details clearfix">
<h3>{{book.name}}</h3>
<p>{{book.price}}</p>
<ul class="list-unstyled list-inline">
<li>Rating: {{book.rating}}</li>
<li>Binding: {{book.binding}}</li>
<li>Publisher: {{book.publisher}}</li>
<li>Released: {{book.releaseDate}}</li>
</ul>
<p>{{book.details}}</p>
<button class="btn btn-info pull-right" ng-click="buy(book)">Buy</button>
</div>
</li>
</ul>
</div>
Problem is how use controller as syntax for kart-list.html near ng-repeat to access kart details?
Your'e using the controller as feature but you haven't covered all view references.
book-list.html
<button ... ng-click="addToKart(book)">Add to Kart</button>
Change to
<button ... ng-click="booklist.addToKart(book)">Add to Kart</button>
kart-view.html
<li ... ng-repeat="book in kart" ...
...
<button ... ng-click="buy(book)">Buy</button>
Change to
<li ... ng-repeat="book in KartListCtrl.kart" ...
...
<button ... ng-click="KartListCtrl.buy(book)">Buy</button>
You have to prefix booklist while calling addToKart() method in book-list.html.
Use below file which will resolve your issue:
book-list.html
<div id="bookListWrapper">
<form role="form">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search here..." />
</div>
</form>
<ul class="list-unstyled">
<li class="book" ng-repeat="book in booklist.books" style="background: white url('imgs/{{book.imgUrl}}') no-repeat">
<div class="book-details clearfix">
<h3>{{book.name}}</h3>
<p>{{book.price}}</p>
<ul class="list-unstyled list-inline">
<li>Rating: {{book.rating}}</li>
<li>Binding: {{book.binding}}</li>
<li>Publisher: {{book.publisher}}</li>
<li>Released: {{book.releaseDate}}</li>
</ul>
<p>{{book.details}}</p>
<button class="btn btn-info pull-right" ng-click="booklist.addToKart(book)">Add to Kart</button>
</div>
</li>
</ul>
</div>

how to get specific item that selected?

screenshot attached.
I learning angularJS.
And i can't find a way to remove the selected item that the 'Remove' button was click on.
Is there any way to do it ?
code attached:
<ul class="unstyled">
<li ng-repeat="todo in todos">
<input type="checkbox" ng-model="todo.done">
<span class="done-{{todo.done}}">{{todo.text}}</span>
<button class="btn" ng-click="removeTodo()">Remove</button>
</li>
</ul>
var app = angular.module("app" , []);
app.controller("MyCtrl" , function($scope){
$scope.todos = [
{"text" :"Learn AngularJS","done":false},{"text" :"build an app","done":false}];
$scope.removeTodo = function(index) {
$scope.todos.splice(index,1);
}
$scope.removeTodo2 = function(todo) {
var index = getByValue( $scope.todos,todo);
$scope.todos.splice(index,1);
}
$scope.addTodo = function(todo){
var toDoObject = {"text":todo,"done":false};
$scope.todos.push(toDoObject);
};
$scope.done = function(todo){
angular.forEach($scope.todos,function(index,todo1){
if(todo == todo1)
$scope.todos[index].done = !$scope.todos[index].done;
})
}
function getByValue(arr, value) {
for (var i=0, iLen=arr.length; i<iLen; i++) {
if (arr[i].text == value) return i;
}
}
});
.done{
text-decoration: line-through;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
<ul class="unstyled">
<li ng-repeat="todo in todos track by $index">
<input type="checkbox" ng-model="todo.done" >
<span ng-class="{'done' : todo.done == true}">{{todo.text}}</span>
<button class="btn" ng-click="removeTodo($index)">Remove</button>
<button class="btn" ng-click="removeTodo2(todo.text)">Remove2</button>
</li>
</ul>
<input type="text" ng-model="todo">
<input type="button" ng-click = "addTodo(todo)" value="Add">
</div>

Can I set `ng-repeat` object as `model` to share the details?

I am using ng-repeat to display a property of an array. and i need further details to share with other elements to from this array. but the element not nested inside of the ng-repeat.
In this case is it possible to set the array object as a model to share the details to other elements?
here is my code :
<ul>
<li ng-click="activate(item)" ng-model="item" ng-repeat="item in items" ng-class="{active : active == item}">
<span ng-if="item == active">
<span>{{item.name}}</span>
<!-- when active nested under span -->
</span>
<!-- else without nesting the span -->
<span ng-if="item !== active">{{item.name}}</span>
</li>
</ul>
<h1>{{item.age}}</h1> //i am trying to fetch model info here
You can make ng-click set the item to a scope variable:
var app = angular.module('app', []);
app.controller('myController', function($scope) {
$scope.items = [{
name: 'a',
age: 12
}, {
name: 'b',
age: 15
}];
$scope.activate = function(item) {
$scope.active = item;
};
});
.active {
color: green;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app='app' ng-controller='myController'>
<ul>
<li ng-click="activate(item)" ng-repeat="item in items" ng-class="{active : active == item}">
<span ng-if="item == active">
<span>{{item.name}}</span>
<!-- when active nested under span -->
</span>
<!-- else without nesting the span -->
<span ng-if="item !== active">{{item.name}}</span>
</li>
</ul>
<h1>{{active.age}}</h1>
</div>

Updating Radio Button Select on Click Parent Element in Angular

Assume this model:
<li ng-repeat="item in documentViews" for ={{item}}>
<div class="col-sm-12 document-view-item" ng-click="change($index)">
<div class="row">
<img class="document-view-img" src="../assets/images/kml_document.png">
</div>
<div class="row">
<input type="radio" ng-model="prefs.documentView" ng-value="item.value" id="{{item.value}}" name="documentView" ng-selected="prefs.documentView">
{{item.key}}
</input>
</div>
</div>
</li>
And this controller:
angular.module('app')
.controller('DocumentViewCtrl', function ($scope) {
$scope.subtitle = 'Default document view';
$scope.documentViews = [
{
key: 'Blah1',
value: 'b1'
},
{
key: 'Blah2',
value: 'b2'
},
];
$scope.change = function($index) {
console.log($scope.documentViews[$index].value);
};
});
I do not want to update the radio button only when selecting the input tag, but when clicking on the higher div element where the ng-click appears. I couldn't get further than triggering a console log when a click occurs and this is fine, but I am wondering how to update the select on the radio button and thus the $scope.
What about something like this?
In your html:
<li ng-repeat="item in documentViews" for="{{item}}">
<div class="col-sm-12 document-view-item" ng-click="change(item)">
<div class="row">
<img class="document-view-img" src="../assets/images/kml_document.png">
</div>
<div class="row">
<input type="radio" ng-model="prefs.documentView" ng-value="item.value" id="{{item.value}}" name="documentView" ng-selected="prefs.documentView">
{{item.key}}
</input>
</div>
</div>
</li>
In your controller:
$scope.change = function(item) {
$scope.prefs.documentView = item.value;
}

Resources