How to remove the list from an array using angular + - angular6

I am using the checkbox to get the list of
below is the data:
data:[{ email: "email1" }, { email: "email2" }, { email: "email3" }, { email: 'email4' }]
html
<table>
<thead>
<th></th>
<th></th>
</thead>
<tbody>
<td *ngFor="let x of collection;">
<input type="checkbox" (change)="checkEmails($event,x)" />
</td>
<td>{{x.email}}</td>
</tbody>
<table>
.ts file
public groupList: any = [];
checkEmails(event, email) {
if (event.target.checked) {
if (this.groupList.length == 0) {
this.groupList.push(email);
}
else {
this.groupList.push(email);
}
console.log("bulkData", this.groupList);
}
}
Now the list is adding into an array..
But when deselecting the checkbox I want to remove the list from an array.
Can anybody help me??

use splice function
checkEmails(event, email) {
if (event.target.checked) {
this.groupList.push(email);
console.log("bulkData", this.groupList);
} else {
for(var i = 0 ; i < this.groupList.length; i++) {
if(this.groupList[i].email == email.email) {
this.groupList.splice(i, 1);
}
}
console.log("bulkData1", this.groupList);
}
}
Working Example : https://stackblitz.com/edit/angular-splice
For more clarification : https://love2dev.com/blog/javascript-remove-from-array/

Related

uncheck a checkbox which is in a for loop through a method

I am having a checkbox inside a for loop and having a array to store the row details. I only wants to select two checkboxes at a time. when a user clicked on the 3rd checkbox, checkbox should be unchecked automatically while giving a toaster messege.
I have tried to implement this and am getting the toaster messege successfully. But 3rd checkbox is not getting unchecked automatically. Please help on this.
HTML
<tr *ngFor="let row of rows$; let indexOfEl = index">
<td><input type="checkbox" value="indexOfEl (change)="onCheckboxChange($event,indexOfEl,row)"/></td>
</tr>
TS file
onCheckboxChange(event: any, index:any, data: any){
if(event?.target?.checked){
if(this.selectedCommand.length < 2){
data.index = index;
this.selectedCommand.push(data);
}
else {
this.sharedService.showErrorNotification('Cannot select more than two commands', 'Error');
}
}
else this.selectedCommand = this.arrayRemove(this.selectedCommand,index);}
arrayRemove(array:any , index:any){
return array.filter(function(element){
return element.index != index;
});
}
I have quickly wrote it out how i would do it. Feel free to use this if it helps.
HTML
<tr *ngFor="let command of commands">
<td>
<input
type="checkbox"
(change)="onCheckboxChange($event, command)"
/>
</td>
</tr>
TS
export class YourComponent {
public selectedCommand: Command[] = [];
public commands: Command[] = [
{ commandName: 'Command 1' },
{ commandName: 'Command 2' },
{ commandName: 'Command 3' },
{ commandName: 'Command 4' },
{ commandName: 'Command 5' }
];
constructor() { }
public onCheckboxChange(event: any, data: Command) {
if (event?.target?.checked) {
if (this.selectedCommand.length < 2) {
this.selectedCommand.push(data);
}
else {
this.sharedService.showErrorNotification('Cannot select more than two commands', 'Error');
event.target.checked = false;
}
}
else {
var indexToRemove = this.selectedCommand.findIndex(x => x.commandName == data.commandName);
this.selectedCommand.splice(indexToRemove, 1);
}
}
}
interface Command {
commandName: string;
}

How to keep state of the checkbox after the reload the page in angular 9?

I am trying to check the multiple checkboxes, when the page reloads, the state is restored to default (unchecked) and I've been buzzing my head with this. by the way I stored the checked value in the local storage but I do not know how to map it to the HTML checkbox for checked when the page reloads. please help me.
.html
<tbody>
<tr *ngFor="let p of pmDetails1">
<td>
<input type="checkbox" name="{{p.id}}" [value]="p.id" (change)="getEmployeeId($event,p.id)">
</td>
<td>
{{p.firstName}} {{p.lastName}}
</td>
<td>
{{p.jobTitle.jobTitleName}}
</td>
</tr>
</tbody>
.ts
ngOnInit() {
this.userService.getAllUsers().subscribe((x: IEmployee[]) => {
this.pmDetails1 = x;
});
this.selectedItem = new Array<number>();
this.selectedEmployee = new Array<number>();
console.log("localStorage", localStorage.getItem("selected"));
this.selectedItem = JSON.parse(localStorage.getItem("selected"));
}
//onSaveEmployee is a function for the button to the confirm that I checked,
onSaveEmployee() {
localStorage.setItem("selected",JSON.stringify(this.selectedEmployee));
}
getEmployeeId(e:any,id:string){
if(e.target.checked){
this.selectedEmployee .push(id);
}
else{
this.selectedEmployee = this.selectedEmployee.filter(m => m!=id);
}
}
IEmployee interface
export interface IEmployee {
id: number;
firstName: string;
jobTitle: any;
lastName: String;
}
Finaly I found a way to do it. its like this.
.html
<tbody>
<tr *ngFor="let p of pmDetails1">
<td>
<input type="checkbox" name="{{p.id}}" [value]="p.id (change)="getEmployeeId($event,p.id)" [checked]="isChecked(p.id)"/>
</td>
<td>
{{p.firstName}} {{p.lastName}}
</td>
<td>
{{p.jobTitle.jobTitleName}}
</td>
</tr>
</tbody>
.ts
ngOnInit() {
this.userService.getAllUsers().subscribe((x: IEmployee[]) => {
this.pmDetails1 = x;
});
if(localStorage.getItem("selected")){
this.selectedEmployee = JSON.parse(localStorage.getItem("selected"));
}
}
// to save checked value
onSaveEmployee() {
localStorage.setItem("selected",JSON.stringify(this.selectedEmployee));
this.dialogRef.close(this.selectedEmployee);
this.selectedEmployee = [];
}
getEmployeeId(e:any,id:string){
if(e.target.checked){
this.selectedEmployee .push(id);
}
else{
this.selectedEmployee = this.selectedEmployee.filter(m => m!=id);
}
}
isChecked(id:number){
for (let index = 0; index < this.selectedEmployee.length; index++) {
if(id == this.selectedEmployee[index]){
return true;
}
}
return false;
}

is there a sorting function given inside the curly braces with column

i have code in which i would like to implement sorting (ascending & descending )onclick on the header
{{getH(col)}}
{{getH(col)}}
i expecting the sorting for the table
To get more responses to your question, best to share what you had tried already... but this is what you're looking for:
each column header calls a function sortBy which sorts by that column, this is done in ascending order by default & sort order is changed to descending (because we needed to toggle the order after each click)
the sortBy function does the sorting and updates the UI as a result
working code snippet below:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.dataset = [{
name: 'ff',
age: '12'
}, {
name: 'gg',
age: '22'
}, {
name: 'jj',
age: '34'
}, {
name: 'dd',
age: '64'
}, {
name: 'hh',
age: '3'
},
{
name: 'ff',
age: '32'
}, {
name: 'bb',
age: '54'
}, {
name: 'aa',
age: '87'
}, {
name: 'ii',
age: '18'
}, {
name: 'cc',
age: '69'
}
];
$scope.nameSort = 'asc';
$scope.ageSort = 'asc';
$scope.sortBy = function(passedTitle) {
if (passedTitle == 'name') {
if ($scope.nameSort == 'asc') {
$scope.dataset.sort(function(a, b) {
var x = a.name.toLowerCase();
var y = b.name.toLowerCase();
if (x < y) {
return -1;
}
if (x > y) {
return 1;
}
return 0;
});
$scope.nameSort = 'desc';
} else {
if ($scope.nameSort == 'desc') {
$scope.dataset.sort(function(a, b) {
var x = a.name.toLowerCase();
var y = b.name.toLowerCase();
if (x > y) {
return -1;
}
if (x < y) {
return 1;
}
return 0;
});
$scope.nameSort = 'asc';
}
}
}
if (passedTitle == 'age') {
if ($scope.nameSort == 'asc') {
$scope.dataset.sort(function(a, b) {
return a.age - b.age
});
$scope.nameSort = 'desc';
} else {
if ($scope.nameSort == 'desc') {
$scope.dataset.sort(function(a, b) {
return b.age - a.age
});
$scope.nameSort = 'asc';
}
}
}
}
});
th,
td {
border: 2px double red;
}
button,
button:focus {
background: transparent;
border: none;
outline: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<thead>
<th> <button type='button' ng-click="sortBy('name')">Name</button></th>
<th> <button type='button' ng-click="sortBy('age')">Age</button></th>
</thead>
<tbody>
<tr ng-repeat='data in dataset'>
<td> {{data.name}} </td>
<td> {{data.age}} </td>
</tr>
</tbody>
</table>
</div>

How to create an Array of actions and implement them in my Angular component?

I have to modify the following code with an implementation of an Array of actions (bottom page).
I saw lots of websites by I wasn't able to find something than can be used for my code.
I will have to change my html , my tableService, my component.ts and oviously my actionConfiguration.
At the moment this is my HTML:
<div class="container">
<table class="table">
<tr>
<th *ngFor="let col of columns" (click)="sortTable(col)">{{col}}</th>
<th>Actions</th>
</tr>
<tr *ngFor="let user of users | paginate: {itemsPerPage: 5,
currentPage: page,
totalItems: users.length } ; let i = index">
<td *ngFor="let col of columns">{{user[col]}}</td>
<td>
<button [ngClass]="getClassCondition(act)" *ngFor="let act of actions" (click)="actionFunc(act,i)">{{act}}</button>
</td>
</tr>
</table>
</div>
<div>
<pagination-controls (pageChange)="page = $event"></pagination-controls>
</div>
This is my component.ts:
#Component({
selector: 'app-dynamic-table',
templateUrl: './dynamic-table.component.html',
styleUrls: ['./dynamic-table.component.css']
})
export class DynamicTableComponent implements OnInit {
#Input()
users = [];
#Input()
columns: string[];
#Input()
actions: string[];
#Input()
class;
direction = false;
page: any;
constructor() {
}
sortTable(param) {
/*done*/
}
actionFunc(i, index) {
if (i === 'deleteUser') {
if (confirm('Are you sure you want to delete this item?') === true) {
this.users.splice(index, 1);
}
}
if (i === 'editUser') {
/*...*/
}
}
getClassCondition(act) {
return act === 'deleteUser' ? this.class = 'btn btn-danger' : 'btn btn-primary' ;
}
ngOnInit(): void {
}
}
This is my tableService.ts
import { USERS } from './mock-data';
#Injectable()
export class TableService {
constructor() { }
static getUsers(): Observable<any[]> {
return Observable.of(USERS).delay(100);
}
static getColumns(): string[] {
return ['id', 'firstName', 'lastName', 'age'];
}
static getActions(): string[] {
return ['deleteUser', 'editUser'];
}
}
Here's the new Task, I have to create an Array of Actions so I will be able to use it in different components but I have no idea how to do it.
I have to start from something like this, it's just an example (not complete because I don't know what to insert exactly):
actionConfig.ts
export const ACTIONS = [
{
label: 'Remove',
actionType: 'deleteUser',
},
{
label: 'Edit',
actionType: 'editUser',
},
];
A sample of Enum and a table to show data on iterating on them:
StackBlitz
You also might want to read typescript-enums-explained
Basically, the TypeScript enums are compiled to something as shown below for reverse lookup. Thats why I have added the foreach loop in constructor and created another list.
export enum Fruits {
APPLE = 'Apple',
MANGO = 'Mango',
BANANA = 'Banana',
}
is compiled to
var Fruit;
(function (Fruit) {
Fruit[Fruit["APPLE"] = 'Apple'] = "APPLE";
Fruit[Fruit["MANGO"] = 'Mango'] = "MANGO";
Fruit[Fruit["BANANA"] = 'Banana'] = "BANANA";
})(Fruit || (Fruit = {}));
UPDATE
HTML
<button [ngClass]="getClassCondition(act.actionType)" *ngFor="let act of actions"
(click)="actionFunc(act, user)">{{act.label}}</button>
COMPONENTS.TS
actionFunc(action, element: any) {
if (action.actionType === 'DELETE') {
if (confirm('Are you sure you want to delete this item?') === true) {
/*...*/
}
}
if (action.actionType === 'GO_TO') {
/*...*/
}
}
actionsConfig.ts
export const ACTIONS = [
{
label: 'Delete',
actionType: 'DELETE',
deleteApi: 'api/USERS'
},
{
label: 'Edit',
actionType: 'GO_TO',
getUrl: row => '/detail/' + row.id,
},
];

Display json data in angular (with typescript)

I posted this one before, but there were not many helpful answers
I have JSON file that contains the following data:
[{
"ID": 1030980,
"Component": "Glikoza (Gluk)",
"Result": "16",
"Date": "20.10.2018"
},
{
"ID": 1030980,
"Component": "Kreatinin (Creat)",
"Result": "5",
"Date": "19.10.2018"
},
{
"ID": 1030989,
"Component": "Urea (UN)",
"Result": "1",
"Date": "19.10.2018"
},
...this goes on and on
]
UPDATE: I added this code to my patients.component:
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-patients',
templateUrl: './patients.component.html',
styleUrls: ['./patients.component.css']
})
export class PatientsComponent implements OnInit {
title = 'Patient Data';
constructor(private http: HttpClient) { }
ngOnInit(): void {
this.http
.get('./assets/patients.json')
.subscribe(res => {
const patients = res['patients'];
const patient = patients[0];
for (let i = 0; i < patients.length; i++) {
let item = patients[i];
console.log(item['ID'], item['date'], item['component'], item['result']);
}
});
}
}
Now, I need to take the 'component' and 'result' by Patient ID and by Date in a row (show the results for each component for different date and ID). The table should show ALL OF THE COMPONENTS AND RESULTS for the specific ID and Date, it should look like this:
table
Could you please give me some pointer? Thanks!
I have it.
Here's the stackblitz : https://angular-aqfdrs.stackblitz.io
What i've done
I've created a dynamic array of array based on the date and the fields you want to be displayed :
public patArray: any[] = [];
this.pat[0].patients.forEach(el => {
if(this.currentDateString == ""){
this.currentDateString = el['date'];
if(!this.skipAssign){
this.patArray[this.idx] = [];
}
}
if(this.currentDateString == el['date']){
this.patArray[this.idx].push(el);
} else {
this.currentDateString = "";
this.idx++;
this.patArray[this.idx] = [];
this.patArray[this.idx].push(el);
this.skipAssign = true;
}
});
Then a nested ngFor with some flex do the tricks:
.flex-ctr{
display: flex;
width:100%;
flex-direction: column;
}
.first{
display: flex;
flex-direction: row;
width:100%;
height:80px;
border: 1px solid;
margin-top: 5px;
}
.tbl{
display: flex;
flex-direction: row;
width:75px;
height:80px;
}
.table-things{
display: flex;
flex-direction: column;
width:100%;
font-size: 10px;
border-right: 1px solid;
text-align: center;
align-content: center;
}
.bb{
border-bottom: 1px solid;
height:30%;
}
.ss{
padding-top: 30px;
}
<div class="flex-ctr">
<div class="first" *ngFor="let data of patArray">
<div class="tbl" *ngFor="let single of data">
<div class="table-things">
<div class="bb">{{single.component}}</div>
<div class="ss">{{single.result}}</div>
</div>
</div>
</div>
</div>
Based on what you have already achieved you are darn close.
1. Create a type for patients (Model)
export class Patient {
constructor(public ID: string,
//ALL THE PROPERTIES OF THE MODEL
) {}
}
2. Bind the model to your Component
Inside your patients.component.ts:
private patients : Patient[] = [];
Before subscribing to the get method on the httpclient. Place your component in a variable so that you can set the model on it:
var self = this; //This is now the PatientsComponent variable
this.http
.get('./assets/patients.json')
.subscribe(res => {
let patients = res['patients'];
let patient = patients[0];
self.patients = patients; //SETTING THE MODEL ON THE COMPONENT
for (let i = 0; i < patients.length; i++) {
let item = patients[i];
console.log(item['ID'], item['date'], item['component'], item['result']);
}
});
3. Build your html template with *ngFor
Inside patients.component.html (edit - bind a list of Components to the component class called components):
<table>
<thead>
<th>ID</th>
<th>Date</th>
<th *ngFor="let component of components">{{ component }}</th>
</thead>
<tbody>
<tr *ngFor="let patient of patients">
<td>{{ patient.ID }}</td>
<td>{{ patient.Date}}</td>
<td *ngFor="let component of components"> {{ (patient.Component === component) ? patient.Result : "-" }}</td>
</tr>
</tbody>
</table>
4. [EDIT] Filter our Patient Results
public static FilterFunc(patients : Patient[]) {
let uniques: Patient[] = [];
patients.forEach(function (value: Patient, index: number) {
if (uniques.some(function (patientCompare: Patient) {
return (patientCompare.Date === value.Date && patientCompare.ID === value.ID && patientCompare.Component === value.Component);
})) {
let updatePatient = uniques.find(function (patientCompare: Patient) {
return (patientCompare.Date === value.Date && patientCompare.ID === value.ID && patientCompare.Component === value.Component);
});
updatePatient.Result += value.Result;
}
else {
uniques.push(value);
}
});
}
So in our edit you need to also bind a components : string[]; object to the component. Which must contain ["crea", "gluk", etc....]
And use the filter function to filter out your data.