jQWidgets Forums
jQuery UI Widgets › Forums › Scheduler › Scheduler Legend does not appear
Tagged: Scheduler Legend
This topic contains 1 reply, has 2 voices, and was last updated by Hristo 4 years, 6 months ago.
-
Author
-
Hello, first of al, thank you for this component.
Unfortunately I have an issue regarding the legend.
probably a setup / configuration mismatch, but I don’t know which one.
no error, just no legend.
please find my code below
thank you for your help
scheduler.component.html file : with showLegend<jqxScheduler class="calendar" theme="'material'" #scheduler [date]="date" [views]="views" [localization]="localization" [resources]="resources" [view]="view" [source]="dataAdapter" [width]="'100%'" [height]="'600'" [showLegend]="'true'" [legendPosition]="'top'" [legendHeight]="'30'" [appointmentDataFields]="schedulerConfig.appointmentDataFields" [editDialog]="EDIT_DIALOG" [contextMenuCreate]="contextMenuCreate" [renderAppointment]="renderAppointment" (onAppointmentClick)="onAppointmentClick($event)" (onDateChange)="onDateChange($event)" (onViewChange)="onViewChange($event)" appCustomTooltip> </jqxScheduler>
scheduler.components.ts file : with resources declaration
import { Component, OnInit, ViewChild, Input, SimpleChanges, OnChanges, AfterViewInit, OnDestroy, IterableDiffers, DoCheck } from '@angular/core'; import { jqxSchedulerComponent } from 'jqwidgets-ng/jqxscheduler'; import { SchedulerSourceModel } from '@app/models/scheduler/source'; import { Ilocalization } from '@app/models/scheduler/localization'; import { ISchedulerConfig } from '@app/models/scheduler/config'; import { IAppointment, IAppointmentData } from '@app/models/scheduler/appointment'; import { IImplantation} from '@app/models/scheduler/implantation'; import { TranslateService } from '@ngx-translate/core'; import * as moment from 'moment'; import { Subject, BehaviorSubject } from 'rxjs'; import { takeUntil, distinctUntilChanged, switchMap, filter } from 'rxjs/operators'; import { ApiService } from '@app/services/api.service'; import { GenericModalService } from '@app/shared/modal/service/generic-modal.service'; interface IPeriod { start: number; period: 'day' | 'week' | 'month'; } @Component({ selector: 'app-scheduler', templateUrl: './scheduler.component.html', styleUrls: ['./scheduler.component.scss'] }) export class SchedulerComponent implements OnChanges, OnInit, DoCheck, AfterViewInit, OnDestroy { @ViewChild('scheduler') sch: jqxSchedulerComponent; @Input() schedulerData: [Ilocalization, ISchedulerConfig, IImplantation[]]; meetingList: IAppointment[]; schedulerConfig: ISchedulerConfig; implantations: IImplantation[]; resources: jqwidgets.SchedulerResources; localization: Ilocalization; dataAdapter: any; views: any; date = new jqx.date(); EDIT_DIALOG = false; periodSubject: BehaviorSubject<IPeriod> = new BehaviorSubject(null); _onDestroy = new Subject(); start: moment.Moment; view: 'dayView' | 'weekView' | 'monthView' = 'monthView'; currentLoadedMeetingDate: moment.Moment; renderAppointment: (data: IAppointmentData) => IAppointmentData; contextMenuCreate: (menu: any, settings: any) => void; private iterableDiffer; constructor(private translateService: TranslateService, private iterableDiffers: IterableDiffers, private overlayService: GenericModalService, private apiService: ApiService) { this.iterableDiffer = this.iterableDiffers.find([]).create(null); } ngOnChanges(change: SimpleChanges) { if (change.meetingList && !change.meetingList.isFirstChange()) { this.buildDataAdapter(); this.sch.source(this.dataAdapter); } } ngOnInit(): void { this.start = moment().startOf('month'); this.currentLoadedMeetingDate = this.start.clone(); this.start.utcOffset(0); this.start.set({ hour: 0, minute: 0, second: 0, millisecond: 0 }); this.start.toISOString(); this.start.format(); this.periodSubject.next({ start: this.start.valueOf(), period: 'month' }); this.localization = this.schedulerData[0]; this.buildScheduler(); this.loadAppointmentByPeriod(); this.loadImplantations(); /********************* Functions ******************* */ this.contextMenuCreate = (menu: any, settings: any) => { if (settings) { settings.source = []; } }; this.renderAppointment = (data: IAppointmentData) => { if (data.view === 'monthView') { data.cssClass = 'month-view-appointment'; data.height = 100; } const eventType = this.getEventTypeCssClass(data.appointment); if (eventType) { data.cssClass = <code>${data.cssClass ? data.cssClass + ' ' : ''}apointment-${eventType}</code>; const subject = data.appointment.subject.replace(/<[^>]+>/g, ''); data.html = subject.substring(Math.min(3, subject.length, subject.length)).trim(); } data.html = '<strong>' + data.html + '</strong>'; if (data.appointment && data.appointment.place) { const logo = this.getCityLogo(data); if (!!logo) { data.html = data.html + <code><br><img class="apointment-location-logo" src="/assets/icons/city/${logo}" /> (${data.appointment.place})</code>; } else { data.html = data.html + <code><br>(${data.appointment.place})</code>; } } return data; }; } ngDoCheck() { const meetingListChange = this.iterableDiffer.diff(this.meetingList); if (meetingListChange) { } } ngAfterViewInit() { } ngOnDestroy() { this._onDestroy.next(); this._onDestroy.complete(); } onAppointmentClick(event: any) { const appointment = event.args.appointment; const parser = new DOMParser(); const str: string = appointment.description; if (str && str.length) { const element = parser.parseFromString(str, 'text/html'); let body = element.getElementsByTagName('body')[0].innerHTML; body = body.replace(/<img\s[^>]*?src\s*=\s*['\"]([^'\"]*?)['\"][^>]*?>/g, ''); this.overlayService.open(body, null, 'center', true, null, '90%'); } } onDateChange(event: any) { const currentDate = moment(event.args.date.toDate()); const isSameMonth = this.currentLoadedMeetingDate.month() === currentDate.month() && this.currentLoadedMeetingDate.year() === currentDate.year(); if (!isSameMonth) { this.currentLoadedMeetingDate = currentDate.clone(); this.date = event.args.date; currentDate.utcOffset(0); currentDate.set({ hour: 0, minute: 0, second: 0, millisecond: 0 }); currentDate.toISOString(); currentDate.format(); const period = {} as IPeriod; period.start = currentDate.valueOf(); period.period = 'month'; this.periodSubject.next(period); } } onViewChange(event: any) { this.view = event.args.newViewType; const currentDate = moment(event.args.date.toDate()).startOf('month'); const isSameMonth = this.currentLoadedMeetingDate.month() === currentDate.month() && this.currentLoadedMeetingDate.year() === currentDate.year(); if (!isSameMonth) { this.currentLoadedMeetingDate = currentDate.clone(); this.date = event.args.date; currentDate.utcOffset(0); currentDate.set({ hour: 0, minute: 0, second: 0, millisecond: 0 }); currentDate.toISOString(); currentDate.format(); const period = {} as IPeriod; period.start = currentDate.valueOf(); period.period = 'month'; this.meetingList = []; this.periodSubject.next(period); } else { const source = this.getSource(this.view); this.updateDataAdapter(source); } } private loadAppointmentByPeriod() { this.periodSubject.pipe( takeUntil(this._onDestroy), filter(query => query !== null), distinctUntilChanged(), switchMap((value: IPeriod) => { return this.apiService.getMeetingList(value.start, value.period); }) ).subscribe((meetingList: IAppointment[]) => { this.meetingList = meetingList; this.buildDataAdapter(); this.sch.source(this.dataAdapter); }); } private buildScheduler(): void { this.schedulerConfig = this.schedulerData[1]; this.views = this.schedulerConfig.views; this.buildDataAdapter(); } private updateDataAdapter(source: SchedulerSourceModel) { this.dataAdapter = new jqx.dataAdapter(source, { autoBind: true }); } private buildDataAdapter(): void { this.dataAdapter = new jqx.dataAdapter(this.getSource(this.view), { autoBind: true }); this.resources = { colorScheme: 'scheme03', dataField: 'id', source: this.dataAdapter }; } private getSource(view: 'dayView' | 'weekView' | 'monthView'): SchedulerSourceModel { return new SchedulerSourceModel( 'array', this.schedulerConfig.dataFields, 'id', this.meetingList, this.translateService.currentLang, view ); } private getEventTypeCssClass(apointment: IAppointment): string { const eventTypes = [ 'evi', 'spu', 'web', 'epm', 'epa', 'com', 'sem']; let eventType = apointment?.subject.replace(/<[^>]+>/g, '').substring(0, 3).toLowerCase(); return eventTypes.find(item => item === eventType); } private getCityLogo(data: IAppointmentData): string { return this.implantations.find((cur: IImplantation) => { let city = cur.cities.find((implantation: string) => { return (<string> data.appointment.place.toLowerCase()).indexOf(implantation) > -1; }); return !!city; })?.logo; } private loadImplantations() { this.implantations = this.schedulerData[2]; } }
_calendar.css with lgend declaration :
.jqx-scheduler-legend { width: 14px; height: 14px; float: left; margin-right: 3px; border-style: solid; border-width: 1px; cursor: pointer; vertical-align: middle; margin-top: 4px; } .jqx-scheduler-legend-label { float: left; margin-right: 12px; cursor: pointer; vertical-align: middle; margin-top: 4px; }
Thank you for your help
Regards
JérômeHello Jérôme,
It is a little bit complicated example (there is missing some settings).
However, I try to create an example closer to your case.
Please, take a look at this example:
https://stackblitz.com/edit/github-aet7ex-eqz7ib?file=src/app/app.component.html
That I change are the values set in string format, for example, theheight
and thelegendHeight
properties.Best Regards,
Hristo HristovjQWidgets team
https://www.jqwidgets.com -
AuthorPosts
You must be logged in to reply to this topic.