Forum
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;
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.
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....
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.
Cok tesekkurler Ali Hocam, hemen bakiyorum.