Angular - inside an ng-repeat, checkbox state to affect only one element - angularjs

If I have for example a simple todo list:
HTML
<ul ng-repeat="todos in keyVar.list">
<li ng-class="{ 'completed' : keyVar.toggle }">
{{ todos }}
<input ng-if="!keyVar.toggle" type = "checkbox" ng-click="keyVar.toggle=true" >
<input ng-if="keyVar.toggle" type = "checkbox" checked= "true" ng-click="keyVar.toggle=false" ></input>
</li>
</ul>
JS
angular.module("todoApp", [])
.controller("mainCtrl", function(){
var keyVar = this;
keyVar.title ="Angular Todos";
keyVar.list=[];
keyVar.toggle = false;
keyVar.todosArr = function(){
keyVar.list.push(keyVar.todo)
keyVar.todo = "";
}
});
When I run this, I can add a todo, and check and uncheck the checkbox which toggles a class of completed, but it gives the class to every todo and if I check one checkbox, all of them go checked. I think I have to use something like keyVar.list[$index]? But I'm not sure where to use it or how.

Try like this. I define for each todo a status. and bind that to checkbox. when user click on checkbox change it.
angular.module("todoApp", [])
.controller("mainCtrl", function(){
var keyVar = this;
keyVar.title ="Angular Todos";
keyVar.list=[
{
"title":"Todo1",
"status":false
},
{
"title":"Todo2",
"status":false
}
];
keyVar.todosArr = function(){
keyVar.list.push({title:keyVar.todo,status:false})
keyVar.todo = "";
}
});
.completed{
text-decoration: line-through;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="todoApp" ng-controller="mainCtrl as keyVar" class="container">
<input type="text" ng-model="keyVar.todo">
<button ng-click="keyVar.todosArr()">Add Todo</button>
<ul ng-repeat="todos in keyVar.list">
<li ng-class="{ 'completed' : todos.status }">
{{ todos.title }}
<input ng-model="todos.status" type = "checkbox" ng-click="keyVar.toggle=true" >
</li>
</ul>
</div>

Try use ng-checked instead of ng-click.
<input ng-if="!keyVar.toggle" ng-checked="keyVar.toggle=true">

Related

Angularjs autocomplete ng-click does not work

I'm trying to write autocomplete in Angularjs. It works for me except the click on the suggestion. From the console log it looks like whenever I click on the suggestion, ng-blur of the input element is called as it input element loses focus and ng-click is never called. Can anybody suggest a solution here?
Here is my code.
<!DOCTYPE html>
<head>
<title>Autocomplete</title>
<style>.wrapper {display: none;}.wrapper ul {list-style-type: none;}.wrapper li {padding: 5px;line-height: 25px;cursor: pointer;}</style>
<!-- Angular JS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.min.js"></script>
</head>
<body ng-app="MyApp">
<div ng-controller="SuggestionCtrl">
<form action="/index.html">
<input type="search" name="q" autocomplete="off"
ng-model="q"
ng-focus="showSuggesions()"
ng-blur="hideSuggesions()"
ng-change="getSuggestion()">
<div class="wrapper"
ng-if="hasSuggestions"
ng-style="suggestionStyle">
<ul>
<li ng-repeat="suggestion in suggestions"
ng-click="search(suggestion)">
{{suggestion}}
</li>
</ul>
</div>
</form>
</div>
var app = angular.module("MyApp", []);
app.controller("SuggestionCtrl", function ($scope) {
$scope.suggestions = ["India", "United States", "England", "Australia"];
$scope.showSuggesions = function () {
$scope.suggestionStyle = { display: "block", 'background-color': '#ddd' };
};
$scope.hideSuggesions = function () {
$scope.suggestionsVisible = false;
$scope.suggestionStyle = { display: "none" };
console.log('hideSuggestions called');
};
$scope.hasSuggestions = function(){
return $scope.suggestions.length > 0;
}
$scope.getSuggestion = function () {
// get suggestions from api
};
$scope.search = function (suggestion) {
window.location = window.location + "?q=" + suggestion;
};
});
The click event executes after blur - list with suggestions hides before you are able to click it. The simple solution is to use mousedown instead of click
<input type="search" name="q" autocomplete="off"
ng-model="q"
ng-focus="show=true"
ng-blur="show=false">
<div class="wrapper"
ng-style="suggestionStyle">
<ul ng-show="show">
<li ng-repeat="suggestion in suggestions">
<a ng-mousedown="search(suggestion)">{{suggestion}}</a>
</li>
</ul>
plunker: http://plnkr.co/edit/Y4e4dYD4qJZwnNRmgWiN?p=preview

how to remove the value of an input field using angularjs

<div class="info-block" ng-app="">
<div ng-controller="Note">
<div class="checkbox">
<label>
<p><b>Primary Publication: </b>
{{ form_widget(form.input_ppubs, { 'attr': {'class': 'valOption'}}) }}
</p>
</label>
</div>
<div ng-repeat="item in items">
<input type="text" placeholder="new input" ng-model="item.primaryPub">
</div>
<button type="button" ng-click="add()">New Item</button>
</div>
I am trying to retrieve the value of the html input field and remove it from input upon a button click
I am able to get the code, but I don't know how to remove the code.
var Note = function($scope){
$scope.items = [];
$scope.add = function () {
//angular way of implementing document.getElementByID();
pub1 = angular.element('#form_input_ppubs').val();
$scope.items.push({
primaryPub: pub1
});
};
}
You don't have to retrieve your items like this. It's ugly and not the angular way. angular.element('#form_input_ppubs').val();
Instead, simply reference it in your input using ngModel.
Declare it in your scope.
$scope.inputItem = null;
HTML
<input ng-model="inputItem " />
Use it in your function:
$scope.addItem = function(item) {
$scope.items.push(item);
//reset the model
$scope.inputItem = null;
}
Call it using ng-click
<button type="button" ng-click="addItem(inputItem)">Add Item</button>
If you do:
console.log($scope.items);
You should see an entry for primaryPub, the model for your input. Then you can target it by nulling the model, so:
$scope.items.primaryPub = null;
However you're using this inside an ng-repeat:
<div ng-repeat="(i, item) in items">
<input type="text" placeholder="new input" ng-model="items[i].primaryPub">
</div>
So your console.log (if you have more than one item in 'items') should show an array-like structure for primaryPub.

Apply logic to every element in an ng-repeat upon ng-click (AngularJS)

I'm trying to build a media library in which only one image can be selected at a time. To do this, I have a list generated with AngularJS's ng-repeat function. So far, when I click on an element, it adds a highlighting class to a child div and toggles the visibility of a child form element. How can I make the click do the opposite for every other element in the ng-repeat?
<li ng-click="show=!show" ng-repeat="media in media">
<div ng-if="show" class="selected">
<input class="bulk-check" type="hidden" name="ids[]" value="#include('_helpers.media_id')">
</div>
</li>
You could just save displayed media in a temp variable in your controller and have 2 functions 1) set the media object on click of item 2) can show function which checks for object equality.
Controller:
var shownMedia = $scope.medias[0]; //Set you default media
$scope.selectMedia = function(media) {
shownMedia = media; //on click, set the new media as selected media
}
$scope.canShow = function(media) {
return angular.equals(shownMedia, media); //Check if this is the displayed media
}
View:
<li ng-click="selectMedia(media)" ng-repeat="media in medias">
{{media.name}}
<div ng-if="canShow(media)" ng-class="{selected : canShow(media)}">
{{media.description}}
<input class="bulk-check" type="hidden" name="ids[]" value="#include('_helpers.media_id')">
</div>
</li>
Example implementation Demo
angular.module('app', []).controller('ctrl', function($scope) {
$scope.medias = [{
name: 'media1',
description: "media1"
}, {
name: 'media2',
description: "media2"
}, {
name: 'media3',
description: "media3"
}];
var shownMedia = $scope.medias[0];
$scope.selectMedia = function(media) {
shownMedia = media;
}
$scope.canShow = function(media) {
return angular.equals(shownMedia, media);
}
});
.selected{
color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<ul>
<li ng-click="selectMedia(media)" ng-repeat="media in medias">
<span ng-class="{selected : canShow(media)}">{{media.name}}</span>
<div ng-if="canShow(media)">
{{media.description}}
<input class="bulk-check" type="hidden" name="ids[]" value="#include('_helpers.media_id')">
</div>
</li>
</ul>
</div>
This should work
<li ng-repeat="media in mediaList" ng-click="media.show=!media.show" >
<div ng-if="media.show" class="selected">
<input class="bulk-check" type="hidden" name="ids[]" value="#include('_helpers.media_id')">
</div>
</li>

angularjs model reload after item delete

I'm pretty new in angularjs and I have no idea how do this.
<div class="userData" ng-repeat="user in users">
<div class="float"
<img ng-click="deleteUser($event)" src="myurl">
</div>
<div class="userDiv"
<input type="checkbox" ng-model="user.active" ng-click="handleUserActive()">
<input type="text" ng-model="user.text">
</div>
</div>
I need remove a item when the user click the img.
My model is:
$scope.users = [
{active: true, text: text}
]
Just do:
<img ng-click="deleteUser($index)" src="myurl">
And the method:
$scope.deleteUser = function(index) {
$scope.users.splice(index, 1)
}
What tymeJV said, however, you want to pass the object as the parameter rather than the index like this:
<img ng-click="deleteUser(user)" src="myurl">
$scope.deleteUser = function(user) {
var index = $scope.users.indexOf(user);
$scope.users.splice(index, 1)
}
The reason why is the index can change if you do an orderBy on the ng-repeat.
See an example here: http://jsfiddle.net/6a5zT/

Angular JS binding scope data within ng-repeat to form

I have a collection of items in $scope.data with fields "id","name" & "age", that are being displayed in the view using ng-repeat directive.
For each set of items, there is a corresponding "edit button".
I want to be able to access values for the particular set of items for which edit button was pressed.
Html:
<div ng-controller="Ctrl">
<div ng-repeat="i in data">
Name: {{i.name}}
Age: {{i.age}}
<form ng-submit="submit()">
<input type="text" ng-model="i.id"/>
<input type="submit" value="Edit" />
</form>
</div>
</div>
Script:
function Ctrl($scope)
{
$scope.data = [
{id:1,name:"Alex",age:22},
{id:2,name:"Sam", age:28}
];
$scope.submit = function() {
//access id of user for which edit was clicked
};
}
What is the right way to do this?
Instead of a form, I would suggest you just use a button:
<div ng-controller="Ctrl">
<div ng-repeat="i in data">
Name: {{i.name}}
Age: {{i.age}}
<input type="text" ng-model="i.id"/>
<button ng-click="submit(i)">Edit</button>
</div>
</div>
Just send i into the button click event (I suppose you could use form if you need validation, but your example doesn't seem to need it).
Your submit function then changes to:
$scope.submit = function(selectedItem) {
// here you now have access to selected item
};
Try this:
HTML:
<form ng-submit="submit(i.id)">
JavaScript:
$scope.submit = function(userId) {
// you have userId
};
One option is to just use an ng-click within a button that calls your submit passing in i
<div ng-controller="Ctrl">
<div ng-repeat="i in data">
Name: {{i.name}}
Age: {{i.age}}
<button ng-click="submit(i);">edit</button>
</div>
</div>
and the function:
$scope.submit = function(i) {
console.log(i);
//access id of user for which edit was clicked
};
Here's a fiddle of that working: http://jsfiddle.net/pRAcP/

Resources