angular change class by id - javascript

I have collection in angular. the collection looks like:
$scope.collection = [{id:'a1', title:'title 1'}, {id:'a2', title:'title 2'}];
<span ng-repeat="c in collection" id="{{c.id}}">{{c.title}}</span>
it is then itterate using ngRepeat in a span tag. in other line i have buttons that have custom property, let say data-span-id, like so:
<button type="button" data-span-id="a1">
<button type="button" data-span-id="a2">
when that buttons clicked, i want to change the class of the span that have id equal to data-span-id property. in jQuery
$('#'+$(this).data('span-id')).addClass('someclass');
how to this in angular? PS: spans and buttons is scallable.

It's hard to answer without seeing more of your code, but something along these lines is how I'd do it....
<button ng-repeat="item in collection" ng-click="selected = item.id">{{ item.title }}</button>
<span ng-repeat="item in collection" ng-class="{ 'someClass': selected == item.id }">{{ item.title }}</span>
So clicking a button sets a variable in the scope to the id you want, and then your span checks for that variable to set a class.

Related

Angular *ngFor "id" tag generation incorrect with `mat-button-toggle`

I'm trying to generate a list of buttons from an array:
<div class="card-container">
<mat-button-toggle *ngFor="let button of buttonsFromApi" id={{button.id}} class="problemButton" [disabled]="sso.invalid" >{{button.id}}</mat-button-toggle>
</div>
buttonsFromApi contains 5 objects like:
{
displayName: "Button name",
id: "100",
}
So basically I want the button to display the displayName (this works) and to have the id that is in the object. The latter of this does not happen, but instead, the button(s) have id(s) like 100-button and 200-button instead of 100 and 200. Why is this and how can I make it so the ids are 100 and 200 instead of 100-button and 200-button?
if you want to override (or better extend) the default-button-id from angular material, you have to pass in the id. (https://material.angular.io/components/button-toggle/api#MatButtonToggle)
<div>
<mat-button-toggle id="test-123" value="right" aria-label="Text align right"></mat-button-toggle>
</div>
the you will get your id inside the component:
<mat-button-toggle ... id="test-123">
<button class="mat-button-toggle-button" type="button" id="test-123-button" tabindex="0" aria-pressed="false" aria-label="Text align right">
<div class="mat-button-toggle-label-content"></div>
</button>
...
</mat-button-toggle>
Id should be assigned in quotes
<div *ngFor="let button of buttonsFromApi" id="{{button.id}}">
<mat-button-toggle>{{button.displayName}}</mat-button-toggle>
</div>
Use attribute binding with square brackets:
<div *ngFor="let button of buttonsFromApi" [attr.id]="button.id">

ng-model with unique id inside ng-repeat ionic 1 angularjs

I want to create like button with ionic 1/angular js.
The problem is when like buttons doesnt work with ng-model within ng-repeat because all ng-model have same names.
This is the html so far.
<div ng-repeat="item in items">
<div class = "item item-text-wrap">
<button class="button button-block icon ion-thumbsup" ng-model="islike" ng-class="islike== true?'button-on':'button-light'" ng-click="changeLikeState(item.id);"> Like</button>
</div>
</div>
I want to initialize the button state if a user already like this item or not. If user already like the item, islike is set to true otherwise islike set to false.
I want to create a function to check like state with $http.get call and set the islike based on the results
The problem is there are multiple item with same islike, How do you set item.id within ng-model="islike" to identify specific button?
Is this the correct approach ? How to solve this in ionic/angularjs?
You don't need an ng-model for buttons. Simply pass the object into your function with ng-click to trigger any changes there. Here is a demo:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.items = [
{"islike":false,"id":1},
{"islike":false,"id":2},
{"islike":false,"id":3},
];
$scope.changeLikeState = function(item) {
item.islike = !item.islike;
console.log(item.id);
}
});
.button-on {
color: blue;
font-weight: bold;
}
.button-light {
color: green;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="item in items">
<button ng-class="{'button-on':item.islike,'button-light':!item.islike}" ng-click="changeLikeState(item);">
Like
</button>
</div>
</div>
as pointed above in the comment islike should be a property of each item in your object, for example :-
let's assume your collection looks something like
$scope.items = [{ name: 'pan cakes', islike: false },
{ name: 'pea nut butter', islike: true },
{ name: 'pizza', islike: true }]
along with other properties if there's an id associated too, that's more than enough otherwise you can always use the $index in ng-repeat to track the current item in items
your code then may look something like this:-
<div ng-repeat="item in items track by ($index)">
<div class = "item item-text-wrap">
<button class="button button-block icon ion-thumbsup" ng-model="item.islike" ng-class="item.islike == true?'button-on':'button-light'" ng-click="changeLikeState($index);"> Like</button>
</div>
</div>
notice the change track by and instead of islike its not item.islike

Click button to copy text to another div with angularjs

I have a list of Items with different button with them. Plunker
Quick View:
I want something like if I click on any of the buttons, related text will be copy to the div above. Also if I click on the button again it will removed from the Div.Same for each of the buttons. [I added manually one to show how it may display ]
I am not sure how to do that in Angular. Any help will be my life saver.
<div ng-repeat="item in csTagGrp">
<ul>
<li ng-repeat="value in item.csTags">
<div class="pull-left">
<button type="button" ng-class='{active: value.active && !value.old}' class="btn btn-default btn-xs">{{value.keys}}</button>
<span>=</span>
</div>
<div class="pull-left cs-tag-item-list">
<span>{{value.tags}}</span>
</div>
</li>
</ul>
</div>
The simplest thing would be to use $scope.tags object to store selected tags and add/remove them with the scope method similar to this:
$scope.tags = {};
$scope.toggleTag = function(tag) {
if (!$scope.tags[tag]) {
$scope.tags[tag] = true;
}
else {
delete $scope.tags[tag];
}
};
Demo: http://plnkr.co/edit/FrifyCrl0yP0T8l8XO4K?p=info
You can use ng-click to put in your scope the selected value, and then display this value instead of "Win".
http://plnkr.co/edit/IzwZFtRBfSiEcHGicc9l?p=preview
<div class="myboard">
<span>{{selected.tags}}</span>
</div>
...
<button type="button" ng-click="select(value)">{{value.keys}}</button>

How to filter a list in AngularJS using several links

I have been going over a lot of tutorials on how to filter a list and can't find an example for my simple use-case.
I have several buttons such as
Name
Age
Height
I have var persons = {...} object and I display it like
<div ng-repeat="person in persons">
{{person.name...}}
</div>
How do I create a filter so each time I will click on one of the buttons the list will be filtered ?
I have tried addingng-repeat="person in persons | filter:filterPersons"
and on the script side to write:
$scope.filterPersons(person){
if (person.name == "John")
return person;
}
but this is only one use-case (how can I filter by another name?) - in other words - How do I connect the links to the filter?
You can bind your filter to scope variables as you do with any other thing. So all you need is to set the appropriated filter to the scope when the user click and bind it to the ng-repeat filter param. See:
<div ng-app>
<span ng-click="myFilter = {type: 1}">Type 1</span> |
<span ng-click="myFilter = {type: 2}">Type 2</span> |
<span ng-click="myFilter = null">No filter</span>
<ul ng-controller="Test">
<li ng-repeat="person in persons | filter:myFilter">{{person.name}}</li>
</ul>
</div>
function Test($scope) {
$scope.persons = [{type: 1, name: 'Caio'}, {type:2, name: 'Ary'}, {type:1, name: 'Camila'}];
}
Notice that the myFilter is changed when the user clicks the filter, and that it's bound to the ng-repeat filter. Fiddle here. You could also create a new filter, but this solution is far better.
My response is very similar to Caio's. I just wanted to show how to filter out an existing array.
In my ng-repeat I have a search filter that goes through the words. I wanted tabs to look for a string match. So I added a additional filter
<tr class="unEditableDrinks" ng-repeat="drink in unEditableDrinkList | orderBy:'-date'|limitTo:400|filter:search |filter:myFilter">
<td>[[drink.name]]</td>
I only have the top part of my table but this should show the strategy. The second filter called myFilter is attached to the buttons below.
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary" ng-click="myFilter={name:'soda'}">Soda</button>
</div>
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary" ng-click="myFilter={name:'energy'}">Energy Drinks</button>
</div>
On each button I am able to add a ng-click that goes through myFilter and searches the td with drink.name. In each ng-click I can set the value of name to search. So every title containing soda or energy can be filtered through.

How to add a dynamic class in knockoutjs?

Let's say i have,
<span class="cls1 cls2" data-bind="title: title" ></span>
I want to add another class via JSON object,
{ title: 'a', clas: 'cls3' }
This work's,
<span class="cls1 cls2" data-bind="attr:{title: title,'class': 'cls1 cls2'+clas}" ></span>
But the problem is that it will add two class attributes. I need the cls1 and cls2 class on beginning. But need cls3 class after some event.
You should use css binding instead of attr for this. Read more about it in the documentation: http://knockoutjs.com/documentation/css-binding.html.
You code will look something like this:
<span class="cls1 cls2" data-bind="text: title, css: myClass" ></span>
Here is working fiddle: http://jsfiddle.net/vyshniakov/gKaRF/
Using multiple classes:
<span
class="yourClass"
data-bind="css: { myClass: (true == true), theirClass: (!true == false), ourClass: true }"
>Thine Classes</span>
You can use the css binding to do this:
<span class="cls1 cls3" data-bind="css: clas"/>
This adds the value of your "clas" property to the current class collection of the element

Categories