Angular DataTable u...
 
Bildirimler
Hepsini Temizle

Angular DataTable uzerinde column filtering  

  RSS
Özhan GÜLAL
(@ozhangulal)
Üye

Herkese Selamlar ! bir proje uzerinde standart bir datatable kullaniyorum ve icerisinde gomulu olarak tum kolonlarda arama yapan bir search input var asagida yer alan gorselde ki gibi; 

Capture

fakat acilen gelen bir talebe gore bu datatable uzerinde yer alan searchun her kolon basinda input olarak yer almasi ve kolon bazli arama yapmasi talep edildi benden;

yine benzer gorseli asagida gorebilirsiniz. 

Capture1

dedigim gibi gorseller temsili fakat .html, service ve component.ts kodlarimi sirasi ile paylasiyorum sizler ile;

.html page;

<kt-portlet>

<kt-portlet-header [class]="'kt-portlet__head--lg'">
<ng-container ktPortletTitle>
<h3 class="kt-portlet__head-title">
<span>All Resources</span>
</h3>
</ng-container>
</kt-portlet-header>

<kt-portlet-body>
<kt-data-table *ngIf="resources$" [dataSource]="resources$ | async" [dtOptions]="dtOptions"></kt-data-table>
</kt-portlet-body>

</kt-portlet>

service.ts

import { Injectable, OnInit } from '@angular/core';
import { HttpClient, HttpEvent, HttpRequest, HttpHeaders } from '@angular/common/http';
import { Observable, of, combineLatest, forkJoin, from } from 'rxjs';
import { AppConfig } from '../../../../environments/app.config';
import { Resource, ResourceSkill } from '../../../../../src/app/core/models/resource.model';
import { DisplayDataModel, DisplayResumeModel } from '../../../core/models/display-data.model';
import { map, catchError, tap, finalize } from 'rxjs/operators';
import { FormGroup } from '@angular/forms';
import { DropdownListService } from '../../partials/content/general/dropdown-list/dropdown-list.service';
import { ProfilePictureService } from '../../partials/content/general/profile-picture/profile-picture.service';
import { ListViewModel, ResourceChart } from '../../../../../src/app/core/models';
import { AvailableResources } from '../../../core/models/resource-chart.model';
import moment from 'moment';

export interface ResourceData {
    formData: FormData;
    resourceForm: any;
    dropdownListKey: string;
    deletedResumes?: DisplayResumeModel[];
    listViewResume$: Observable<DisplayResumeModel[]>;
}

@Injectable({
  providedIn: 'root'
})
export class ResourceService {

    constructor(
        private http: HttpClient,
        private dropdownListService: DropdownListService,
        private profilePicService: ProfilePictureService
    ) {
     }

    getResource(id: string): Observable<Resource> {
        return this.http.get<Resource>(AppConfig.getResource + id);
    }

    getResources(): Observable<Resource[]> {
        return this.http.get<Resource[]>(AppConfig.getResourceList);
    }

    deleteResource(id: any) {
        return this.http.delete(AppConfig.deleteResource + id);
    }

    addResource(resource: FormData): Observable<string> {
        return this.http.post<string>(AppConfig.addResource, resource);
    }

    updateResource(resource: FormData) {
        return this.http.post<Resource>(AppConfig.updateResource, resource);
    }

    downloadResume(id: number): Observable<Blob> {
        return this.http.get(AppConfig.downloadResume + id, {
            responseType: 'blob'
        });
    }

    getFormData(resourceData: ResourceData): Observable<FormData> {
        return forkJoin([
            this.dropdownListService.getListView(resourceData.dropdownListKey),
            resourceData.listViewResume$,
            from(this.profilePicService.getImageFileToSave()),
        ]).pipe(
            map(([skills, resumes, image]) => {
            this.setFormValues(resourceData.formData, resourceData.resourceForm);
            resourceData.formData.append('resourceSkillsAsString', this.getResourceSkills(skills));
            resourceData.formData.append('imageFile', image);
            for (const file of this.getNewResumes(resumes)) {
                resourceData.formData.append('files', file);
            }
            for (const removedResumeId of this.getDeletedResumes(resourceData.deletedResumes)){
                resourceData.formData.append('removedResumeIds', removedResumeId);
            }
            return resourceData.formData;
        }));

    }

    getDataTableOptions(self): DataTables.Settings {
        const dtOptions = {
            columns: [
                {
                    title: 'Name',
                    data: 'displayName',
                    render(data: any, type: any, row: any) {
                        return `<a href="${AppConfig.detailResourcePage}${row.id}" class="resourceName">${data == null ? row.firstName + " " + row.lastName : data}</a>`;
                    },
                    createdCell(cell, cellData, rowData) {
                        const resourceNode = $(cell).find('a.resourceName');
                        if (resourceNode) {
                            resourceNode.on('click', (event: any) => {
                                event.preventDefault();
                                self.navigateToPage(AppConfig.detailResourcePage + rowData.id);
                            });
                        }
                    }
                },
                {
                    title: 'Email',
                    data: 'email'
                },
                {
                    title: 'Experience Level',
                    data: 'experienceLevelName'
                },
                {
                    title: 'Actions',
                    data: null,
                    orderable: false,
                    render(data: any, type: any, row: any) {
                        return `<a class="resourceEdit fa fa-edit icon" href="${AppConfig.editResourcePage}${row.id}">
                </a>
                <a elementId="${row.id}" class="deleteResource fa fa-trash icon--delete">
                </a>`;
                    },
                    createdCell(cell, cellData, rowData) {
                        const resourceNode = $(cell).find('a.resourceEdit');
                        const deleteResource = $(cell).find('a.deleteResource');

                        if (resourceNode && deleteResource) {
                            resourceNode.on('click', (event: any) => {
                                event.preventDefault();
                                self.navigateToPage(AppConfig.editResourcePage + rowData.id);
                            });

                            deleteResource.on('click', (event: any) => {
                                event.preventDefault();
                                self.deleteResource(rowData.id);
                            });
                        }
                    }
                }
            ],
            lengthMenu: [5, 10, 25]
        };
        return dtOptions;
    }

    getResourceExperienceLevels(): Observable<DisplayDataModel[]> {
        return this.http.get<any[]>(AppConfig.getExperienceLevels).pipe(
            map(experienceLevels => {
                let displayData: DisplayDataModel[];
                displayData = experienceLevels.map(experienceLevel => {
                    return {
                        id: experienceLevel.id,
                        value: experienceLevel.name
                    };
                });

                return displayData;
            })
        );
    }

    getResourceChartData(): Observable<ResourceChart> {
        return this.http.get<ResourceChart>(AppConfig.getResourceChartData);
    }

    getAvailableResources(): Observable<AvailableResources[]> {
        return this.http.get<AvailableResources[]>(AppConfig.getAvailableResources);
    }

    getFutureAvailableResources(): Observable<AvailableResources[]> {
        return this.http.get<AvailableResources[]>(AppConfig.getFutureAvailableResources);
    }

    getProfilePicture(id: string): Observable<File> {
        return this.http.get(AppConfig.getProfilePicture + id, { responseType: 'blob' }).pipe(
            map((response: Blob) => {
                if (response.size !== 0) {
                    if(!navigator.msSaveBlob)
                    {
                        return new File([response], 'profileImage.' + response.type.split('/')[1] , { type: response.type });
                    }else{
                        return response as File;
                    }
                }
            }),
            catchError((err) => {
                console.error(err);
                return of({} as File);
            })
        );
    }

    instantiateResource(): Resource {
        const resource = {}  as Resource;
        return resource;
    }

    private setFormValues(formData: FormData, resourceForm: any) {
        for (const key in resourceForm) {
            if (resourceForm.hasOwnProperty(key)) {
                if (resourceForm[key]) {
                    formData.append(key, resourceForm[key]);
                }
            }
        }
    }

    private getResourceSkills(resourceSkills: ListViewModel[]): string {
        return JSON.stringify(resourceSkills.map((resourceSkill) => {
            const data: ResourceSkill = {
                skillId: resourceSkill.id,
                id: resourceSkill.resourceSkillId,
                skillRating: resourceSkill.skillRating || 0,
                createdBy: resourceSkill.createdBy,
                createdOn: resourceSkill.createdOn,
                timestamp: resourceSkill.timestamp,
            };
            return data;
        }));
    }

    private getNewResumes(resumes: DisplayResumeModel[]): File[] {
        if (resumes && resumes.length !== 0) {
            return resumes.filter(resume => !resume.fileId).map(resume => resume.file);
        }
        return [];
    }

    private getDeletedResumes(resumes: DisplayResumeModel[]): string[] {
        if (resumes && resumes.length !== 0) {
            return resumes.map(resume => resume.fileId.toString());
        }
        return [];
    }

    private imageExists(image_url: string): Boolean {

        var http = new XMLHttpRequest();
    
        http.open('HEAD', image_url, false);
        http.send();
    
        return http.status != 404;  
    }

    getDashboardDataTableOptions(self, isForBenched: Boolean): DataTables.Settings {
        var srv = this;
        var dtOptions;
        if(isForBenched) {
            dtOptions = {
                columns: [
                    {
                        data: 'pictureId',
                        render(data: any, type: any, row: any) {                            
                            if(data) {
                                return `<img src="${(AppConfig.getResourcePicture + row.resourceId)}" class="profilePicture" style="height:35px; width:35px;">`
                            } else {
                                return `<img src="/assets/media/images/default-user-image.png" class="profilePicture" style="height:35px; width:35px;">`
                            }                           
                        },
                        width: "5%"
                    },
                    {
                        data: 'resourceName',
                        render(data: any, type: any, row: any) {
                            return `<span style="color: #45474f; font-weight: bold; font-size: 12px;">${data}</span>`                               
                        },
                        width: "60%"
                    },
                    {
                        data: 'allocationPercentage',
                        render(data: any, type: any, row: any) {                        
                            return `<span style="color: #45474f; font-weight: bold; font-size: 12px;">%${data}</span>`                                                                  
                        },
                        width: "10%"
                    },
                    {
                        data: null,
                        render(data: any, type: any, row: any) {
                            return `<a class="btn btn-primary visitProfile" style="background-color: #CCE5FC !important; 
                            color: #198CF7 !important; border-color: white; font-weight: bold; width:100%" href="${AppConfig.detailResourcePage}${row.resourceId}">Visit Profile</a>`;
                        },
                        createdCell(cell, cellData, rowData) {
                            const resourceNode = $(cell).find('a.visitProfile');
    
                            if (resourceNode) {
                                resourceNode.on('click', (event: any) => {
                                    event.preventDefault();
                                    self.navigateToPage(AppConfig.detailResourcePage + rowData.resourceId);
                                });
                            }
                        }
                    }
                ],
                searching: false,
                ordering: false,
                paging: false,
                info: false,
                scrollY: "200px",
                scrollCollapse: true
            };
        } else {
            dtOptions = {
                columns: [
                    {
                        data: 'pictureId',
                        render(data: any, type: any, row: any) {                            
                            if(data) {
                                return `<img src="${(AppConfig.getResourcePicture + row.resourceId)}" class="profilePicture" style="height:35px; width:35px;">`
                            } else {
                                return `<img src="/assets/media/images/default-user-image.png" class="profilePicture" style="height:35px; width:35px;">`
                            }   
                        },
                        width: "5%"
                    },
                    {
                        data: 'resourceName',
                        render(data: any, type: any, row: any) {    
                            var formattedDate = moment(new Date(row.availableDate)).format('DD/MM/YYYY');                       
                            return `<span style="color: #45474f; font-weight: bold; font-size: 12px;">${data}</span> <br>
                                    <span style="color: #a0a1a8; font-size: 12px;"> ${formattedDate}</span>`                                                
                        },
                        width: "69%"
                    }, 
                    {
                        data: null,
                        render(data: any, type: any, row: any) {
                            return `<a class="btn btn-primary visitProfile" style="background-color: #CCE5FC !important; 
                            color: #198CF7 !important; border-color: white; font-weight: bold; width:100%" href="${AppConfig.detailResourcePage}${row.resourceId}">Visit Profile</a>`;
                        },
                        createdCell(cell, cellData, rowData) {
                            const resourceNode = $(cell).find('a.visitProfile');
    
                            if (resourceNode) {
                                resourceNode.on('click', (event: any) => {
                                    event.preventDefault();
                                    self.navigateToPage(AppConfig.detailResourcePage + rowData.resourceId);
                                });
                            }
                        }
                    }
                ],
                searching: false,
                ordering: false,
                paging: false,
                info: false,
                scrollY: "200px",
                scrollCollapse: true
            };
        }
        
        return dtOptions;
    }

}
son olarak ise component.ts

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { Resource } from '../../../../core/models/index';
import { Store } from '@ngrx/store';
import * as fromApp from '../../../../core/reducers/index';
import { selectAll, selectAllResourcesForDataTable } from '../../../../core/selectors/resource.selector';
import { Router } from '@angular/router';
import { LayoutUtilsService } from '../../../../core/_base/crud';
import * as fromResource from '../../../../core/actions/resource.actions';
import { ResourceService } from '../resource.service';
import { skip } from 'rxjs/operators';

@Component({
  selector: 'kt-view-resources',
  templateUrl: './view-resources.component.html',
  styleUrls: ['./view-resources.component.scss']
})
export class ViewResourcesComponent implements OnInit {

    resources$: Observable<Resource[]>;
    dtOptions: DataTables.Settings;

    constructor(
        private store: Store<fromApp.AppState>,
        private resourceService: ResourceService,
        private layoutUtilsService: LayoutUtilsService,
        private router: Router
    ) { }

    deleteResource(id: any) {
        const title = 'Record Delete';
        const description = 'Are you sure to permanently delete this record?';
        const waitDesciption = 'Record is deleting...';

        const dialogRef = this.layoutUtilsService.deleteElement(title, description, waitDesciption);
        dialogRef.afterClosed().subscribe(res => {
            if (!res) {
                return;
            }
            this.store.dispatch(new fromResource.ResourceDelete(id));
        });
    }

  ngOnInit() {
        this.store.dispatch(new fromResource.ResourceMultipleGet());
        this.resources$ = this.store.select(selectAllResourcesForDataTable()).pipe(skip(1));
        this.dtOptions = this.resourceService.getDataTableOptions(this);
  }

    private navigateToPage(url: string) {
        this.router.navigateByUrl(url);
    }

}

ilgilenirseniz minnettar kalirim simdiden. Tesekkurler, iyi calismalar....

Bu konu 3 ay önce Hakan Uzuner tarafından düzenlendi
Alıntı
Gönderildi : 23/07/2020 11:51
Ali UYSAL
(@aliuysal)
Kıdemli Üye Forum Yöneticisi

Merhabalar; 
Ag-Grid gibi bir eklenti kullansanız daha kolay olur gibi. Hem ücretsiz sürümüyle bu istediğiniz ve çok daha fazlasına sahip olabilirsiniz.

Dijital dönüşüm başlıyor...
WinFlow e-Fatura Onay Akış Süreç Yazılımı
Android El Terminali

CevapAlıntı
Gönderildi : 25/07/2020 12:59
Özhan GÜLAL
(@ozhangulal)
Üye

Cok tesekkurler Ali Hocam, hemen bakiyorum.

CevapAlıntı
Gönderildi : 25/07/2020 18:38
Paylaş: