jQWidgets Forums
-
Search Results
-
Hi
In my angular 8 app, i have loaded the jqxGrid as follows
view
<jqxGrid [selectionmode]="'checkbox'" [source]="source" [theme]="'material'" [autoheight]="true" [pageable]="true" [altrows]="true" [filterable]="true" [sortable]="true" [columns]="columns" #grid> </jqxGrid>
compoenent
export class CertificateBuilderComponent implements OnInit, AfterViewInit { @ViewChild('grid', { static: false }) grid: jqxGridComponent; columns : any = [ {text: 'Id', datafield: 'id', width : 10}, {text: 'title', datafield: 'title'}, { text: 'Edit', width: 100, datafield: 'Edit', columntype: 'button', cellsrenderer: function (cellvalue, options, rowObject) { return '<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="" onclick="somet1()">Edit</button>'; } } ]; //other code here }
when the grid loads it shows like this:
But the issue i’m having is, when the user clicks a bootstrap edit button it should fetch the data in that row, how do i do this in angular and also how to an execute a function in the component’s class on that button click?
thanks
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ômeHi
i have created the following service
@Injectable() export class LMSVideoResulful { getVideos( enrolmentId : number ) :Observable<Array<Video>> { var x = new Array<Video>(); //https://www.youtube.com/embed/MV0vLcY652c x.push( new Video( "SQL 1", "https://www.youtube.com/embed/qMvDsarDdK0", "sdsdssdss" )); x.push( new Video( "SQL 2", "https://www.youtube.com/embed/hVBALRtY8g0", "sdsdssdss" )); x.push( new Video( "SQL 3", "https://www.youtube.com/embed/qMvDsarDdK0", "sssdssds" )); x.push( new Video( "SQL 4", "https://www.youtube.com/embed/8Fo_KTDrBSU", "sdsdssdss" )); return from([x]); } }
The model
Video
export class Video{ constructor( public title : string, public videoUrl: string, public description : string ){} }
Component class
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core'; import {Input } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; import { LMSVideoResulful } from '../../LMSServices/LMSVideos.service' import { Video } from '../../LMSServices/video.model'; import{ jqxListBoxComponent } from 'jqwidgets-ng/jqxlistbox'; @Component({ selector: 'app-video-list', templateUrl: './video-list.component.html', styleUrls: ['./video-list.component.css'] }) export class VideoListComponent implements OnInit{ safeURL : any; videoList : Array<Video> @ViewChild('listBoxReference', { static: false }) myListBox: jqxListBoxComponent; constructor( private _sanitizer: DomSanitizer, public myVideoService : LMSVideoResulful ){ this.safeURL = this._sanitizer.bypassSecurityTrustResourceUrl("https://www.youtube.com/embed/MV0vLcY652c"); this.myVideoService.getVideos(1).subscribe( x => { this.videoList = x; console.log(JSON.stringify(x)); }, error => error) } //access stored object onChange(e){ console.log("select cahnge::" + e.args.item.label ); } ngOnInit(){ } }
The View
<jqxListBox #listBoxReference [width]="100" (onChange)="onChange($event)"> <ul> <li *ngFor="let v of videoList"> {{v?.title}} </li> </ul> </jqxListBox>
Issue #1
At the moment i can bind only a simple value. But assume i would want to bind an object array to listbox, how do i bind an object array? ( the Binding must be like how we do in drop downs, which has a value and a display text. So the object “Video” property ‘title’ must be display text and property “videoUrl” must the value of each list item )Issue #2
How do i access each select item’s display text and value ?thanks
Hi,
I’ve used the demo at https://www.jqwidgets.com/jquery-widgets-documentation/documentation/phpintegration/php-server-side-grid-crud.htm to create a page that has a connection to a database. The page has 2 Grids (Master Details) and in the 1st Grid it has 2 cells per row that can be updated.
Row gemigreerd is a boolean.
Row notities is a string.When I do an update to a cell i got the error message: Call to a member function bind_param() on bool in C:\xampp\htdocs\DUO\getdata1.php on line 22.
The correct update query is done to the getdata1.php file. GET /duo/getdata1.php?update=true&ID=3&samaccount=4&gebruikersnaam=Roland+Verheijden&percgereeduser=20&gemigreerd=true¬ities=heeft+spoed&uid=3&boundindex=2&uniqueid=2627-24-19-30-242529&visibleindex=2&_=1604865024986Here is my getdata1.php
<!DOCTYPE html> <html lang="en"> <head> <title id="Description">DUO Dashboard</title> <link rel="stylesheet" href="jqwidgets/styles/jqx.base.css" type="text/css" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1 maximum-scale=1 minimum-scale=1" /> <script type="text/javascript" src="scripts/jquery-1.11.1.min.js"></script> <script type="text/javascript" src="jqwidgets/jqxcore.js"></script> <script type="text/javascript" src="jqwidgets/jqxbuttons.js"></script> <script type="text/javascript" src="jqwidgets/jqxdata.js"></script> <script type="text/javascript" src="jqwidgets/jqxdata.export.js"></script> <script type="text/javascript" src="jqwidgets/jqxmenu.js"></script> <script type="text/javascript" src="jqwidgets/jqxpanel.js"></script> <script type="text/javascript" src="jqwidgets/jqxscrollbar.js"></script> <script type="text/javascript" src="jqwidgets/jqxgrid.js"></script> <script type="text/javascript" src="jqwidgets/jqxgrid.sort.js"></script> <script type="text/javascript" src="jqwidgets/jqxgrid.filter.js"></script> <script type="text/javascript" src="jqwidgets/jqxgrid.edit.js"></script> <script type="text/javascript" src="jqwidgets/jqxgrid.export.js"></script> <script type="text/javascript" src="jqwidgets/jqxgrid.selection.js"></script> <script type="text/javascript" src="jqwidgets/jqxlistbox.js"></script> <script type="text/javascript" src="jqwidgets/jqxcheckbox.js"></script> <script type="text/javascript" src="jqwidgets/jqxgrid.columnsresize.js"></script> <script type="text/javascript" src="jqwidgets/jqxdropdownlist.js"></script> <script type="text/javascript" src="scripts/demos.js"></script> <script type="text/javascript"> $(document).ready(function () { var sourceUsers = { datatype: "json", cache: false, datafields: [ { name: 'ID', type: 'number' }, { name: 'samaccount', type: 'string' }, { name: 'gebruikersnaam', type: 'string' }, { name: 'percgereeduser', type: 'number' }, { name: 'gemigreerd', type: 'bool' }, { name: 'notities', type: 'string' } ], id: 'ID', url: './getdata1.php', updaterow: function (rowid, rowdata, commit) { console.log(rowid, rowdata, commit); // synchronize with the server - send update command rowdata.ID = rowid; var data = "update=true&" + $.param(rowdata); $.ajax({ dataType: 'json', url: './getdata1.php', cache: false, data: data, success: function (data, status, xhr) { // update command is executed. commit(true); }, error: function (jqXHR, textStatus, errorThrown) { commit(false); } }); } } var dataAdapterUsers = new $.jqx.dataAdapter(sourceUsers); // initialize jqxGrid $("#userGrid").jqxGrid( { width: 1060, height: 400, source: dataAdapterUsers, // theme: 'material', columnsresize: true, showfilterrow: true, sortable: true, filterable: true, editable: true, keyboardnavigation: true, columns: [ { text: 'Gebruikersnaam', datafield: 'gebruikersnaam', editable: false, width: 275 }, { text: 'User % gereed', datafield: 'percgereeduser', editable: false, width: 125 }, { text: 'Gemigreerd', datafield: 'gemigreerd', columntype: 'checkbox', editable: true, width: 100 }, { text: 'Notities', datafield: 'notities', editable: true } ] }); // events // $('#userGrid').on('cellclick', function (event) { // $("#log").html("A cell has been clicked:" + event.args.rowindex + ":" + event.args.datafield); // }); // Packages Grid // prepare the data var sourceDetails = { datatype: "json", cache: false, datafields: [ { name: 'ID' }, { name: 'samaccount' }, { name: 'gebruikersnaam' }, { name: 'applicatienaam' }, { name: 'percgereedpackage' }, { name: 'omschrijving' }, { name: 'afdeling' }, { name: 'actief' }, { name: 'typewerkplek' } ], id: 'ID', url: 'getdata2.php', }; var dataAdapterDetails = new $.jqx.dataAdapter(sourceDetails); dataAdapterDetails.dataBind(); $("#userGrid").on('rowselect', function (event) { if (event.args.row) { var samaccount = event.args.row.samaccount; var records = new Array(); var length = dataAdapterDetails.records.length; for (var i = 0; i < length; i++) { var record = dataAdapterDetails.records[i]; if (record.samaccount == samaccount) { records[records.length] = record; } } var dataSource = { datafields: [ { name: 'ID' }, { name: 'samaccount' }, { name: 'gebruikersnaam' }, { name: 'applicatienaam' }, { name: 'percgereedpackage' }, { name: 'omschrijving' }, { name: 'afdeling' }, { name: 'actief' }, { name: 'typewerkplek' } ], localdata: records } var adapter = new $.jqx.dataAdapter(dataSource); // update data source. $("#packageGrid").jqxGrid({ source: adapter }); } }); // $("#userGrid").on("cellvaluechanged", function (event) { // var selectedrowindex = $("#userGrid").jqxGrid('getselectedrowindex'); // var datarow = $("#userGrid").jqxGrid('getrowdata', selectedrowindex); // var rowscount = $("#userGrid").jqxGrid('getdatainformation').rowscount; // if (selectedrowindex >= 0 && selectedrowindex < rowscount) { // var id = $("#userGrid").jqxGrid('getrowid', selectedrowindex); // $("#userGrid").jqxGrid('updaterow', id, datarow); // } // }); $("#packageGrid").jqxGrid( { width: 1060, autoheight: true, keyboardnavigation: false, columnsresize: true, sortable: true, columns: [ { text: 'Gebruikersnaam', columntype: 'textbox', datafield: 'gebruikersnaam' }, { text: 'Applicatienaam', columntype: 'textbox', datafield: 'applicatienaam' }, { text: 'App % gereed', columntype: 'textbox', datafield: 'percgereedpackage' }, { text: 'Omschrijving', columntype: 'textbox', datafield: 'omschrijving' }, { text: 'SAM Account naam', columntype: 'textbox', datafield: 'samaccount' }, { text: 'Afdeling', columntype: 'textbox', datafield: 'afdeling' }, { text: 'Actief', columntype: 'textbox', datafield: 'actief' }, { text: 'Type werkplek', columntype: 'textbox', datafield: 'typewerkplek' } ] }); $("#userGrid").jqxGrid('selectrow', 0); }); </script> </head> <body class="default"> <div id="jqxWidget" style="font-size: 13px; font-family: Verdana; float: left;"> <h3> Gebruikers</h3> <div id="userGrid"> </div> <!-- <div id="log"></div> <div id="log1"></div> --> <h3> Details</h3> <div id="packageGrid"> </div> </div> </body> </html>
Table in MySQL is:
CREATE TABLE
sfuser` (
ID
int(11) NOT NULL,
samaccount
text NOT NULL,
gebruikersnaam
text NOT NULL,
percgereeduser
int(11) NOT NULL,
gemigreerd
tinyint(4) NOT NULL,
notities
text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;`Hope you can help me?