Angular - How to include button event? - javascript

Is there a way to include button in this code which will with click make the same change to an array the same way [ngStyle] does in the following part of the code?
app.component.html
<div class="styling">
<ul>
<li *ngFor = "let a of arr"
[ngStyle]="changeFont()">
{{a}}
</li>
</ul>
</div>
app.component.ts
arr=['car','house','beach','microphone'];
changeFont(){
return {'font-size.px':15}
}

In Angular you has variables in .ts, and use this variables in the .html.
An example
style:any=null //declare a variable
toogleStyle() //A function that change the variable
{
if (!this.style)
this.style={'font-size':'15px';color:'red'}
else
this.style=null
}
You can use
<div (click)="toogleStyle()" [ngStyle]="style">click me!</div>
And see how change the style
As you has "severals" <li> you need severals variables if you want severals<li> can be "selected" at time or an unique variable if only one <li> can be selected at time.
The "severals variables" are an Array, so to change one element of
the array you need pass the "index" of the array
styles:any[]=[]
toogleStyle(index:number) //A function that change the variable
{
if (!this.styles[index])
this.styles[index]={'font-size':'15px';color:'red'}
else
this.styles[index]=null
}
<ul>
<!--see using let i=index, i becomes value 0,1,2,3...->
<li *ngFor = "let a of arr;let i=index"
<!--see you pass the "index" to the function-->
[ngStyle]="styles[i]" (click)="toogleStyle(i)">
{{a}}
</li>
</ul>
The unique variable is a number that is the "index" selected. For no
selected index, the variable becomes -1 (Remember that 0 is the fisrt
element of the array)
selectedIndex:number=-1
toogleStyle(index:number) //A function that change the variable
{
if (this.selectedIndex==index) //if you click on selected <li>
this.selectedIndex=-1;
else
this.selectedIndex=index;
}
<ul>
<li *ngFor = "let a of arr;let i=index"
<!--you use the conditional operator (condition)?
value if condition is true:
value if condition is false
-->
[ngStyle]="i==selectedIndex?
{'font-size':'15px';color:'red'}:
null"
(click)="toogleStyle(i)">
{{a}}
</li>
</ul>

Related

Get index of an element from a NodeList

I have a simple list:
<ul id="list">
<li id="item-1">1</li>
<li id="item-2" style="display: none">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
</ul>
And need to get index of a specific item disregarding hidden items.
var list = document.getElementById('list');
var items = list.querySelectorAll('li:not([style*="display: none"])');
I try to convert NodeList in Array:
var list_items = Array.from(items);
But don't known how to run something like that: list_items.indexOf('item-3')
https://codepen.io/marcelo-villela-gusm-o/pen/RwNEVVB?editors=1010
You can make a function to find the id you need in a list you want, passing two parameters, that way you can use this function dynamically.
Based on id, inside the function just need to use .findIndex() that returns the index or -1 if not found.
See here:
var list = document.getElementById('list');
var items = list.querySelectorAll('li:not([style*="display: none"])');
var list_items = Array.from(items);
function getIndexById(idToSearch, list){
//ES6 arrow function syntax
return list.findIndex(elem => elem.id == idToSearch)
//normal syntax
//return list.findIndex(function(elem) {return elem.id == idToSearch})
}
console.log("found at index: ", getIndexById("item-3", list_items))
<ul id="list">
<li id="item-1">1</li>
<li id="item-2" style="display: none">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
</ul>
Not exactly related to the question, but if possible, I would suggest you to change your HTML to remove that inline style of display: none and change it to a class, (e.g: class='hidden'), it would be better for your .querySelector when using :not, for example: li:not(.hidden), since any space in your inline style can break your selector. ("display:none" != "display: none", spot the space)
Maybe like this:
var item = list_items.find(function(item) {
return item.id === "item-3";
});
I would recommend using :not(.hidden) instead of "grepping" for a match on the style tag. Then, simply find the index after casting the NodeList to an array.
For the Vue.js inclined, see this fiddle: https://jsfiddle.net/634ojdq0/
let items = [...document.querySelectorAll('#list li:not(.hidden)')]
let index = items.findIndex(item => item.id == 'item-4')
console.log('item-4 index in visible list is', index)
.hidden {
display: none;
}
<ul id="list">
<li id="item-1">1</li>
<li id="item-2" class="hidden">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
</ul>
Maybe you can use map. First you can create an object with id and value. Then use map function to create array of this object. Then you can access it with foreach, when id = 'item-3'.

ng-checked not working for multiple condition expression in angular js template

I want to check the Users check box on selection of category. But when there is no key for Category in usr_cat array previously checked check boxes not unchecked. I want to uncheck all the users when Manager is selected in the category.
Category = [{cid:'1',name:'Head'},cid:'2',name:'Manager'}]
users = [0:{'id':10,name:'AAAAA'},{'id':12,name:'BBBBB'},{'id':13,name:'CCCCC'},{'id':14,name:'DDDDDDDD'}]
usr_cat = ['1':[10,14]]
Category List
<ul class="list-unstyled cat-lst">
<li ng-repeat = "cat in categery" ng-click ="selectcategry(cat.cid)>{{cat.name}} </li>
<ul>
User List
<ul class="list-unstyled usr-lst">
<li ng-repeat = "usr in users">
<span class=" checkbox ">
<input class="optionChechk " id="user_{{usr.id}}" type="checkbox" ng-checked = "{{usr_cat[sele_cid] != 'null' && usr_cat[sele_cid] != 'undefined' && usr_cat[sele_cid] != '' && (usr_cat[sele_cid].indexOf(usr.id) != -1)}}" ng-value="{{usr.id}}" >
<label for="user_{{usr.id}}" txt = "{{usr_cat[sele_cid]}}">{{usr.name}}</label>
</span>
<li>
</ul>
JS
$scope.selectcategry = function(cid){
$sele_cid = cid;
}
Hi the code contains many error
Angular braces are used inside ng-attributes.
improper closer of quotes"".
Improper naming standards camel-casing is the format.
Category is the variable you mentioned spelling categery is used
everywhere.
<ul class="">
<li ng-repeat = "cat in categery"
ng-click ="selectcategry(cat.cid)">{{cat.name}}</li>
</ul>
Array responses are seem to inValid,suggested bellow,scope is missing in sele_cid
$scope.categery =[{"cid":'1',"name":'Head'},{"cid":'2',"name":'Manager'}];
$scope.users = [{'id':10,"name":'AAAAA'},{'id':12,"name":'BBBBB'}, {'id':13,"name":'CCCCC'},{'id':14,"name":'DDDDDDDD'}];
$scope.usr_cat = [10,14];
$scope.selectcategry = function(cid){
$scope.sele_cid = cid;
}
please work on this

Add style to specific element angular 6

I have the following block of code in the front-end:
<li *ngFor = "let cat of this.dataCategory.iconTitleSet" (click)="getTypeFromCategory(cat.title)" class="list-group-item puntero">
<img [src]="cat.icon" alt="icon" title="icon" />{{cat.title}}
</li>
in the component:
getTypeFromCategory(tipo: string) {
this.typeItem = tipo.toLowerCase();
if (this.arrayTipo.includes(this.typeItem)) {
const i = this.arrayTipo.indexOf( this.typeItem );
this.arrayTipo.splice( i, 1 );
} else {
this.arrayTipo.push(this.typeItem);
}
}
in synthesis what up to now does is add a value that I get from FRONTEND in an array in case it is not, and if it eliminates it from the array, but when I add it I also want to put a specific style, for example a yellow background, but this last I do not know how to do it, I do not know how to say to angular that I put a specific style in element "li" specific generated by an "ngfor" loop when I click on the element.
this is the image in the frontend
You can do it in some ways:
1. to set a diffrennt class with [ngClass]="" to each li and style in css
for example:
<li *ngFor = "let cat of this.dataCategory.iconTitleSet;let i=index;" [ngClass]="'title_'+i" (click)="getTypeFromCategory(cat.title)" class="list-group-item puntero">
<img [src]="cat.icon" alt="icon" title="icon" />{{cat.title}}
</li>
in css:
.title_1{}
2. you can set it with [ngStyle] or style.
<li *ngFor = "let cat of this.dataCategory.iconTitleSet;let i=index;" [style.color]="cat.color" (click)="getTypeFromCategory(cat.title)" class="list-group-item puntero">
<img [src]="cat.icon" alt="icon" title="icon" />{{cat.title}}
</li>
You can do the following.
HTML
<li *ngFor = "let cat of this.dataCategory.iconTitleSet; let i = index" (click)="getTypeFromCategory(cat.title, index)" class="list-group-item puntero" [class.changeColor]="i == selectedValue">
<img [src]="cat.icon" alt="icon" title="icon" />{{cat.title}}
Component
selectedValue: any;
getTypeFromCategory(tipo: string, index) {
this.selectedValue = index;
this.typeItem = tipo.toLowerCase();
if (this.arrayTipo.includes(this.typeItem)) {
const i = this.arrayTipo.indexOf( this.typeItem );
this.arrayTipo.splice( i, 1 );
} else {
this.arrayTipo.push(this.typeItem);
}
}
class changeColor will be applied to every list item selected.

How to display following object in angular5 html file?

In the above screenshot console I have an object with 2 values users and tickers. Again each one is array of values.
Now how to display these values in angular5 html template as specified in above screenshot?
I am trying to use ngFor but it is showing errors.
Suppose this is your data:
public data = {
tickers:[
{id:"1",name:"Ticker Name 1", company:"Company 1"},
{id:"2",name:"Ticker Name 2", company:"comapny 2"}
],
users:[
{id:"1",first_name:"User1 ", last_name:"u1last", email:"user1#test.com"},
{id:"2",first_name:"User2", last_name:"u2last", email:"user2#test.com"},
{id:"3",first_name:"User3", last_name:"u3last", email:"user3#test.com"},
{id:"4",first_name:"User4", last_name:"u4last", email:"user4#test.com"}
]
};
public dataKeys; // This will hold the main Object Keys.
The constructor will look something like this:
constructor() {
this.dataKeys = Object.keys(this.data);
}
Here is the simple HTML that you need to write:
<div *ngFor="let key of dataKeys">
<h3>{{ key }}</h3>
<ul>
<li *ngFor="let d of data[key]">{{d.name || d.first_name}}</li>
</ul>
</div>
Here is the complete working plunker for your case:
Click here to view the Working Solution
you can use like that,
<ul>
<P>users</p>
<li *ngFor="let item of object.users; let i = index">
{{i}}. {{item.frist_name}}
</li>
<P>Tickets</p>
<li *ngFor="let item of object.tickers; let i = index">
{{i}}. {{item.name}}
</li>
</ul>
According to the documentation it should be this:
Users:
<ol>
<li *ngFor="let user of users">{{user.first_name}}</li>
</ol>
Tickets:
<ol>
<li *ngFor="let ticket of tickets">{{ticket.name}}</li>
</ol>
You can use json pipe for debug purpose like this:
{{object |json}}
If you want exactly as in picture, look at this solution. With this case, you don't need to manually write first level property names of object in template for using *ngFor

How to initialize ng-model of input checkboxes in an ng-repeat loop

I've run into an issue when creating multiple input[checkbox]es for a list of items in angular with ng-repeat and attaching an ng-model:
<li ng-repeat="item in items">
<a ng-href="#/{{item.id}}" > {{ item.id }} </a>
<input type="checkbox" ng-model="selectedMessages[item.id]"/>
</li>
The issue here is that selectedMessages[item.id] is only initialized and set when the checkbox is clicked once.
The reason this is necessary is that I would like to toggle all checkboxes with a single comand like so:
$scope.toggleCheckboxes = (state) ->
for key, val of $scope.selectedMessages
$scope.selectedMessages[key] = state # true or false
Let's say I have 3 checkboxes, and click 1 once, 2 twice, and 3 never, then said object will look like this:
$scope.selectedMessages = {
"1" : true,
"2" : false
}
So obviously, $scope.toggleCheckboxes(true) will only work for those checkboxes.
Is there a good way to initialize this ng-model for multiple checkboxes?
You can use ng-init to populate the array. I used $index rather than making up a bunch of data with id properties...adjust your code accordingly
<input type="checkbox"
ng-model="selectedMessages[$index]"
ng-init="selectedMessages[$index]=selectedMessages[$index]||false" />
JS
$scope.selectedMessages=[];
$scope.checkAll=function(){
var msgs = $scope.selectedMessages
msgs.forEach(function(elem, idx){
msgs[idx] =true
})
}
DEMO

Categories

Resources