Configure Edit, New, Delete buttons on Editor datatable with API calls in angular 6 project.
Configure Edit, New, Delete buttons on Editor datatable with API calls in angular 6 project.
I'm trying to implement the Edit, New and Delete buttons to an Editor datatable i've created in an angular. Basicly i populate the editor through an API call on my service and now i want to manipulate this data and pass it back. But i lack experience with angular to really find the solution to my problem. I am at this state:
Component.ts file:
ngOnInit() {
//this.dataTable = $(this.table.nativeElement);
// this.dataTable.dataTable();
this.survService.getClientData(this.jwt).subscribe(
data => {
this.items = data;
this.loadOrganisations(),
console.error();
console.log(this.items);
});
}
public loadOrganisations(): void{
if (this.tableWidget) {
this.tableWidget.destroy(); // essentially refreshes the table
// you can also remove all rows and add new
this.tableWidget.clear().rows.add(this.items).draw();
}
console.log(this.items);
let editor = new ($.fn.DataTable as any).Editor({
ajax:{
edit:{
contentType:'application/json',
data:function (d) {
var newdata;
$.each(d.data, function (key, value) {
newdata = this.survService.client
console.log("ajax data new data...:" + newdata);
});
console.log("ajax data new data:" + newdata);
// // newdata = newdata.replace(/\\n/g, "\\n")
// // .replace(/\\'/g, "\\'")
// // .replace(/\\"/g, '\\"')
// // .replace(/\\&/g, "\\&")
// // .replace(/\\r/g, "\\r")
// // .replace(/\\t/g, "\\t")
// // .replace(/\\b/g, "\\b")
// // .replace(/\\f/g, "\\f");
// // newdata = newdata.replace(/[\u0000-\u0019]+/g,"");
return newdata;
},
success: function (data) { $('#dataTables').dataTable().api().ajax.reload(); },
},
},
table: '#dataTables',
fields:[{
label:"GUID",
name:"guid",
},{
label:"Client Id",
name:"clientId",
},{
label:"Organization Name",
name:"clientName",
},{
label:"Address",
name:"address",
},{
label:"Email",
name:"email",
},{
label:"Responsible Person",
name:"responsiblePersonName",
},{
label:"Work Flow Code",
name:"workFlowCode",
}]
});
let tableOptions: any = {
table: '#dataTables',
data: this.items,
dom: 'Bfrtip',
select: true,
columns: [
//{ title: 'GUID', data: 'guid' },
{ title: 'Client Id', data: 'clientId' },
{ title: 'Organization Name', data: 'clientName' },
{ title: 'Address', data: 'address' },
{ title: 'Email', data: 'email' },
{ title: 'Responsible Person', data:'responsiblePersonName' },
{ title: 'Work Flow Code', data: 'workFlowCode' }
],
buttons: [
{ extend: "create", editor: editor },
{ extend: "edit", editor: editor },
{ extend: "remove", editor: editor }
],
}
this.backofficeTable = $(this.el.nativeElement.querySelector('table'));
this.tableWidget = this.backofficeTable.DataTable(tableOptions);
this.tableWidget.on('select', (e, dt, type, indexes) => {
// // I DIDN'T TRY THIS IN HERE...Just debug it and check the best way to emit an actual object
this.organisationSelected.emit(this.items[indexes[0]]);
});
}
Service.ts file:
getClientData(jwt): Observable<any>{
this.headers = this.headers.set('Authorization', jwt);
return this.httpClient.get<Orgnanisations[]>(
environment.surveyApiUrl + 'api/client/',
{ headers:this.headers,
responseType: 'json' }
);
}
i get this error when i press one of the buttons:
'core.js:1673 ERROR TypeError: Cannot read property 'oFeatures' of undefined'
Any help is more than welcomed.
This question has an accepted answers - jump to answer
Answers
Could you show me the full back trace of the error please? I don't immediately see anything wrong with the above code, but I'm not at all well versed in Angular myself I'm afraid.
Allan
Hello, sorry for the late response, this is my error appearing on the console:
core.js:1673 ERROR TypeError: Cannot read property 'oFeatures' of undefined
at f._tidy (dataTables.editor.min.js:102)
at f.edit (dataTables.editor.min.js:53)
at r.action (dataTables.editor.min.js:122)
at l (dataTables.buttons.min.js:13)
at HTMLButtonElement.<anonymous> (dataTables.buttons.min.js:14)
at HTMLButtonElement.dispatch (jquery.js:5237)
at HTMLButtonElement.elemData.handle (jquery.js:5044)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:3811)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
defaultErrorLogger @ core.js:1673
push../node_modules/@angular/core/fesm5/core.js.ErrorHandler.handleError @ core.js:1719
push../src/app/monitoring/error.handler.ts.MonitoringErrorHandler.handleError @ error.handler.ts:15
next @ core.js:4311
schedulerFn @ core.js:3551
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub @ Subscriber.js:192
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next @ Subscriber.js:130
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next @ Subscriber.js:76
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ Subscriber.js:53
push../node_modules/rxjs/_esm5/internal/Subject.js.Subject.next @ Subject.js:47
push../node_modules/@angular/core/fesm5/core.js.EventEmitter.emit @ core.js:3535
(anonymous) @ core.js:3842
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:391
push../node_modules/zone.js/dist/zone.js.Zone.run @ zone.js:150
push../node_modules/@angular/core/fesm5/core.js.NgZone.runOutsideAngular @ core.js:3779
onHandleError @ core.js:3842
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.handleError @ zone.js:395
push../node_modules/zone.js/dist/zone.js.Zone.runTask @ zone.js:198
push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:498
invokeTask @ zone.js:1744
globalZoneAwareCallback
That error suggests that the DataTable as been replaced. Is it possibly you have another element of the same id on the page, or possibly Angular has replaced the element (I don't know enough about Angular to say if that might be the case I'm afraid).
If you can give me a link to the page I can take a look and see if that might be what is happening.
Thanks,
Allan
Unfortunatly i can't share it, since its not a personal project. I believe this error has to do with the fact that after i populate the dataTable on ngOnInit() method with the subscribe data, that data is no longer accessible by the datatable to pass that row data in the editor modal. Do you have any way to store the data and keep it accessible for the Editor?
Are you using the Angular-Datatables NPM package? Because Datatables.net does not really support any sort of direct manipulation via Angular 2+ without it. Therefore, you have use the Angular package to get the tables to render and then find ways to hook in for the rest of the functionality. It can be a challenge.
First, how are you binding your data to the html element for the datatable? I can tell you that I struggled with the async nature of Angular and Ajax until I bound the dtOptions property of the
<table>
element to a property of my controller (i.e. code-behind .ts file).So, my html looks like:
The variable
myDatatableSettings:Datatables.Settings
contains the .columns array with the data bindings as well as the .data array of all the data. Additionally, you should be able to attach Angular events tomyDatatableSettings.editor.events
or some such.If you make it that far, you should be able to set some breakpoints and catch the api variable that's typically passed into the event handlers and the use that to reference the data. For example, if the index of the edited row is passed into the event,
api.rows(index).data()
should reveal the data.This is just the general theory of how the pieces should fit together. Personally, I took a look at the Editor extension several days ago and thought it was a bit of a mess for doing what should be pretty simple stuff, esp in Angular. So, I just made some nice modal forms and manually wired up the CRUD methods to do it all myself. Was much simpler. Good luck. Let me know if this was helpful or totally messed you up
Oh good grief the comment stripped out my html. I'll use braces instead of angles. Here's my table element:
{table *ngIf="isDataReady" datatable [dtOptions]="myDatatableSettings" class="table hover blah blah"}{/table}
You need to use backticks to show code - otherwise it is stripped on display (not on store - I've added the Markdown formatting needed to your post).
Thanks for your thoughts - we haven't integrated DataTables / Editor with Angular at all (yet? Not yet sure if we will!) so I'm not surprised that it is proving to be a bit difficult. You've got two different libraries trying to control the DOM and there will need to be a bridge between them to make sure the expected interactions apply.
Hopefully without Angular it isn't a "mess" though .
Allan
Sorry, Allan. I wasn't trying to be "that guy" on the Internet. The extension looks very feature rich. I was just a bit overwhelmed by seeing how much re-definition of the fields had to take place apart from the dt columns already defined, I know it makes sense for customizing the modal but was hoping that there was a default mode (did I miss it?) where the existing columns could be flagged with 'editor:true' or something and the plugin would interpolate the data type of the data and present accordingly.
At any rate, I will try it again when it's available for Angular. I would have to do too much plumbing I'm afraid to tie the Ajax calls to my service layer. Thanks again. For a free library it is very, very impressive.
No worries - there is a reason why WTFs/minute is funny .
You didn't miss it I'm afraid. Back when I first started writing Editor I did consider that, but I quickly hit the fact that columns and fields don't always map 1:1. Even something as simple as using a renderer to combine two fields into a single one column caused issues (since you need a way to then define both fields).
For that reason the fields and columns need to be configured in their own objects.
Allan
I finaly found a solution to this. Basicly with custom modals for the button functionality, but at the very least they work.
Now i have a problem in production. We use Azure tech to deploy our projects in production. Localy everything works fine. But on live server i get this error:
ERROR TypeError: $.fn.DataTable.Editor is not a constructor
asociated with this warning:
If you are seeing this message, it is because Editor has been
scripts.f10d58363cdee5a6e2ff.js:1 installed using
npm install datatables.net-editor
, but thescripts.f10d58363cdee5a6e2ff.js:1 licensed or trial files have not been installed in place of
scripts.f10d58363cdee5a6e2ff.js:1 the holding files.
scripts.f10d58363cdee5a6e2ff.js:1
scripts.f10d58363cdee5a6e2ff.js:1 To install the files, please download Editor from
scripts.f10d58363cdee5a6e2ff.js:1 https://editor.datatables.net and replace the Javascript and
scripts.f10d58363cdee5a6e2ff.js:1 CSS files in
node_modules/datatables.net-editor
with thosescripts.f10d58363cdee5a6e2ff.js:1 from the downloaded package.
install.sh
can be used toscripts.f10d58363cdee5a6e2ff.js:1 install the files from the downloaded zip.
main.db272d5f762fbcc2d56a.js:1 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
I have a developer license for editor datatables.
Any idea how to solve this issue?
Have you followed the steps explained in the error message?
I managed to fix it with a little tweek on server side.
Now for anyone who is struggling with the same original error i had, this is the solution i followed:
then declared the buttons:
Hope this can help anyone with the same problem.