Difficulty passing plain object data to edit()
Difficulty passing plain object data to edit()
I have a table that shows two different types of items (say cats and dogs) with mostly common fields. When a user clicks the Edit button, I want the editor to open based on the type of item (cat or dog) that is selected.
Using this (somewhat pseudo-code) example: (the edit button for the table is the part I'm working on)
var editor_for_cats = new $.fn.dataTable.Editor({
...
fields: [{
label: "Id",
name: "id",
}, {
label: "Pet type",
name: "pet_type"
}, {
label: "Name",
name: "name"
}, {
label: "Description",
name: "description"
}]
...
})
var editor_for_dogs = new $.fn.dataTable.Editor({
...
fields: [{
label: "Id",
name: "id",
}, {
label: "Pet type",
name: "pet_type"
}, {
label: "Name",
name: "name"
}, {
label: "Description",
name: "description"
}]
...
})
var table = table.DataTable({
...
buttons: {
...
buttons: [{
extend: "create",
editor: editor
}, {
text: "Edit pet",
action: function(e, dt, node, config) {
var row = dt.row({ selected: true }).row()
var data = row.data()
if (data.pet_type == "cat") {
editor_for_cats.edit(row, { <-- passing the row node
title: "Edit record",
buttons: "Update"
})
} else {
editor_for_dogs edit(row, { <-- passing the row node
title: "Edit record",
buttons: "Update"
})
}
}
}]
},
columns: [{
title: "Id",
name: "id",
data: "id"
}, {
title: "Pet type",
name: "pet_type",
data: "pet_type"
}, {
title: "Name",
name: "name",
data: "name"
}, {
title: "Description",
name: "description",
data: "description"
}]
...
})
The problem I'm having is that the edit()
call to the editor isn't passing along the row data:
var row = dt.row({ selected: true }).row()
...
editor_for_cats.edit(row, { <-- passing the row node
...
})
This page on the edit()
: https://editor.datatables.net/reference/api/edit()
states:
"Rows: This is the default mode of operation and if anything other than a plain object is passed in, the value is used as a row-selector to select the rows to edit. This can be table row nodes, a jQuery selector or row indexes. Please refer to the DataTables row-selector for full information on this data type."
I've tried passing the passing along the data as a plain object:
var row = $(dt.row({ selected: true }).row())
var data = row.data()
...
editor_for_cats.edit(data , { <-- passing the data as an object
...
})
And even tried passing along the jQuery version of the node:
var row = dt.row({ selected: true }).row()
var jQrow = $(row)
...
editor_for_cats.edit(jQrow, { <-- passing the row node as jQuery
...
})
I can get the data to populate using field().set()
:
var row = dt.row({ selected: true }).row()
var data = row.data()
...
editor_for_cats.edit(null, { <-- passing null and then setting individual fields
...
})
.field("id").set(7)
.field("pet_type").set(data.pet_type)
.field("name").set(data.name)
.field("description").set(data.description)
But then the json that is sent to the server is: (notice [object Object]
where the id normally is)
data[[object Object]][id]: 7
data[[object Object]][pet_type]: cat
data[[object Object]][name]: Fernando
data[[object Object]][description]: Nothing special
Although I'm looking for any point in the right direction, it's not clear to me why the plain object approach wouldn't work unless it's expecting something additional with the object, such as:
{
data: {
row data here
}
}
Which I also tried, although it didn't work :-(
This question has an accepted answers - jump to answer
Answers
The key I believe is you need to pass in a valid
row-selector
. You are trying to pass in the data or the row API. See the duplicate button example which shows how to pass the row index. For your case with just one row you would usedt.row({ selected: true }).row().index()
.Kevin
Thanks, Kevin (@kthorngren) -- I've tried that as well, but it seems that because I'm not setting the table option for the editors it doesn't know which table to pull the data from:
Of course I can set the table option but then I get problems later with using something like:
Using this example: https://editor.datatables.net/examples/simple/inTableControls.html
it looks like just a row node is passed:
I might be confused - aren't you using a single table but want two different editor instances depending on the pet type?
Kevin
I put together a basic example of what you described and it seems to work by passing
dt.row({ selected: true }).index()
:http://live.datatables.net/guwafemu/249/edit
If you are having difficulties with
table.editor().destroy()
or something else pleas update the test case to show the issues.Kevin
This is not doing what you think. First its returning the select row (
dt.row({ selected: true })
). Then its returning the row with index 0 (.row()
). Make sure to remove the.row()
.Kevin
Dang it, Kevin -- you've given a perfect example based on my explanation!
Unfortunately I have oversimplified the explanation of what I'm trying to do so that it didn't become a doctoral thesis!
What I'm actually trying to do is make a file directory using DataTables and child rows containing more DataTables.
The initial list of folders for the root directory are rows in a DataTable.
Those rows can be expanded with child rows to show the folder contents in more DataTables, which can be either more folders (that can also expand) or files.
In the end, there could be many open tables, each representing the contents of a folder.
The two editors I have are one for folders and one for files.
The basic structure is:
Using this structure I could have any number of DataTables but still just the two editors without any specific
table
specified.It still seems to me that using the
dt
parameter it should work, since thedt
parameter is dependent on which particular Edit button was pushed:However this only works if I specify a
table
for each editor.I realize the
dt.row({ selected: true }).index()
won't work because the editor has only an index to go off of and doesn't know which table to reference.However it would seem that I could pass something like
dt.row({ selected: true }).node()
or$(dt.row({ selected: true }).node())
or$(dt.row({ selected: true }).data())
and the editor would have the information to populate the fields.In the case of the "In table form controls": https://editor.datatables.net/examples/simple/inTableControls.html
All that's passed along is
$(this).closest('tr')
, but of course it does have thetable
specified, so that's obviously helping the editor to figure out which specific row.Any thoughts?
Ah, and ignore that
var row = dt.row({ selected: true }).row()
.That was a typo from my pseudo-code.
I was using just
var row = dt.row({ selected: true })
Have you seen this blog about using Editor with child detail rows as Datatables?
Looks like the intention is to pass the child Datatbles API into the
table
option.Kevin
I have seen that . It was the original basis for my page, although I've changed it around significantly.
The main difference is the blog creates a separate editor for each child row whereas I'm using the same editor(s) for all the tables.
I can't remember now why I changed that, but I might need to go back to that.
@kthorngren Kevin -- just following up. I put the editors inside the
create_child(row)
function and passed along the table, like what is shown in the blog post, and everything works fine, except . . .It appears multiples editors cannot use the same
template
, which I remember now is why I moved the editors outside the function to use just two editors (one for folders and one for files) for all the DataTables.I suppose I could create local versions of the template in each
create_child(row)
function or perhaps using thetemplate()
to specify it each time might work, but for now I'm just using the standard editor form, which is sufficient.Anyway, as always -- thanks for the quick and persistent assistance!
So actually -- let me follow up -- I cannot duplicate the issue with using the
template
, so I'm not sure what I might have had incorrect.Anyway, it's all working now like I would expect!!!
Fantastic! Glad its working now.
Kevin