Getting Uncaught Unable to automatically determine field from source. Please specify the field name.
Getting Uncaught Unable to automatically determine field from source. Please specify the field name.
I have page with datatable with editor in responsive mode with drag drop for reordering rows. The server side is written in Laravel PHP (not using the editor php library). I don't use the editor's modal and buttons. I use page page fields, jquery and datatable/editor api to communicate with server. Everything works fine (Create, Update and Delete). But when I delete a record, I get "Uncaught Unable to automatically determine field from source. Please specify the field name." in the console, even though the delete logic perfectly completes and table is refreshed correctly.
The DataTables debugger id is: iyefiz.
Below is my code:
<table id="tests-table" class="table table-bordered table-striped" cellspacing="0" width="100%">
<thead>
<tr>
<th style="width: 40px;">Item #</th>
<th>Test Description</th>
<th class="text-right" style="width: 80px;">Price<br>AED</th>
<th style="width: 40px;">Action</th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="2" class="text-right">Total (AED):</th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
<script type="text/javascript">
var myTestDataEditor;
$(document).ready(function() {
var numFormat = $.fn.dataTable.render.number( '\,', '.', 2).display;
myTestDataEditor = new $.fn.dataTable.Editor({
ajax: {
url: "{{ route('quotes.quoteTests.cud', $quote->id)}}",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
},
table: "#tests-table",
idSrc: "quoteTest.id",
fields: [
{ label: 'Item #', name: 'quoteTest.printOrder' },
{ label: 'Description', name: 'quoteTest.test' },
{ label: 'Price', name: 'quoteTest.price' },
{ name : "quoteTest.testPriceCurrencyId", type: "hidden" },
{ name : "quoteTest.testAction", type: "hidden" },
]
});
var myTestDataTable = $('#tests-table').DataTable({
responsive: {
details: {
renderer: function ( api, rowIdx, columns ) {
//test renderer taken from: https://datatables.net/reference/option/responsive.details.renderer
var data = $.map( columns, function ( col, i ) {
return col.hidden ?
'<tr data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
'<td><span class="dtr-title">'+col.title+': '+'</span></td> '+
'<td class="dtr-data">'+col.data+'</td>'+
'</tr>' :
'';
} ).join('');
return data ?
$('<table/>').append( data ) :
false;
}
}
},
order: [[ 0, "asc" ]],
lengthMenu: [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
columns: [
{ "data": "quoteTest.printOrder", "className": 'reorder' },
{ "data": "quoteTest.test" },
{ "data": "quoteTest.price", "className": "text-right", render: $.fn.dataTable.render.number( ',', '.', 2) },
{ "orderable" : false },
{ "data": "quoteTest.testPriceCurrencyId" },
{ "data": "quoteTest.testAction" },
],
columnDefs: [
{
"targets": 3,
"render": function ( data, type, row, meta ) {
return '<button type="button" class="btn btn-box-tool delete-row" data-dt-row="'+meta.row+'"><i class="fa fa-close"></i></button>';
}
},
{
"targets": [4, 5],
"visible": false
}
],
rowReorder: {
dataSrc: 'quoteTest.printOrder',
editor: myTestDataEditor,
update: false,
snapX: -5
},
processing: true,
serverSide: true,
ajax: {
url: "{{ route('quotes.quoteTests.indexData', $quote->id)}}",
data: function ( d ) {
d.serverSide = 'true'; // send this to the server
// d.custom = $('#myInput').val();
// etc
}
},
select: false,
buttons: [
],
"footerCallback": function ( row, data, start, end, display ) {
var api = this.api(), data;
// Remove the formatting to get integer data for summation
var intVal = function ( i ) {
return typeof i === 'string' ?
i.replace(/[\$,]/g, '')*1 :
typeof i === 'number' ?
i : 0;
};
// Total over all pages
total = api
.column( 2 )
.data()
.reduce( function (a, b) {
return intVal(a) + intVal(b);
}, 0 );
// Update footer
$( api.column( 2 ).footer() ).html(
numFormat(total)
);
}
});
myTestDataEditor
.on( 'initCreate', function () {
// Enable order for create
myTestDataEditor.field( 'quoteTest.printOrder' ).enable();
} )
.on( 'initEdit', function () {
// Disable for edit (re-ordering is performed by click and drag)
myTestDataEditor.field( 'quoteTest.printOrder' ).disable();
} );
// Activate an inline edit on click of a table cell
$('#tests-table').on( 'click', 'tbody td:not(:first-child)', function (e) {
myTestDataEditor.inline( this, {
submit: 'allIfChanged',
buttons: { label: '>', fn: function () { this.submit(); } }
} );
} );
// Remove a Quote Item
$('#tests-table tbody').on( 'click', 'button.delete-row', function () {
// the 'this' below uses the data-dt-row set on the button to identify the row
var row = myTestDataTable.row( this );
//console.log(row.data());
myTestDataEditor
.remove( row, false )
.submit();
} );
$('#submit-new-test-button').click(function(e){
// get field values
var test = $('#test').val();
console.log("Test is: " + test);
var testAction = $('#testAction').val();
console.log("Test action is: " + testAction);
var price = $('#price').val();
console.log("Price is: " + price);
var currencyId = $('#testCurrencyId').val();
console.log("Currency Id is: " + currencyId);
// Submit
myTestDataEditor
.create( false )
.set( 'quoteTest.test', test )
.set( 'quoteTest.testAction', testAction)
.set( 'quoteTest.testPriceCurrencyId', currencyId )
.set( 'quoteTest.price', price )
.submit(
function success(serverReturnedData) {
showAlert('test-product', 'success', 'Test created and added to quote successfully.');
//clear up the fields
$('#test').val('');
$('#price').val('');
$('#testCurrencyId').val('');
$('#test-currency').text('');
$('#test-product-section').delay(3000).slideUp("slow");
if ($('#test-toggle-button').html() == '<span class="fa fa-plus"></span> Add Test') {
$('#test-toggle-button').html('<span class="fa fa-minus"></span> Add Test');
} else {
$('#test-toggle-button').html('<span class="fa fa-plus"></span> Add Test');
}
},
function error(serverReturnedData) {
if (serverReturnedData.error) {
showAlert('test-product', 'danger', serverReturnedData.error);
}
if (serverReturnedData.fieldErrors) {
for(i=0; i<serverReturnedData.fieldErrors.length; i++) {
if (serverReturnedData.fieldErrors[i].name == 'quoteTest.test') {
$('#test').closest('.form-group').addClass('has-error');
$('#test').closest('.form-group').find('.help-block').text(serverReturnedData.fieldErrors[i].status);
}
}
}
}
);
});
});
</script>
Even though it is not required, after record is deleted I tried passing the deleted record's data from server also, but it doesn't work either, getting same error.
What could be going wrong?
Thanks.
Velu
This question has an accepted answers - jump to answer
Answers
That's weird. On delete there should be no need for it to look up the field values! Are you able to give me a link to a page showing the issue please?
One thing I see in the above, could you change
{ "orderable" : false },
to be{ "data": null, "orderable" : false },
- otherwise DataTables will automatically assign thedata
property to match the column index.Allan
Hi Allan,
I have emailed you the link and details with the subject "Regarding forum discussion # 45103".
Thanks for your help.
Regards,
Velu
Thanks! I'll reply here if that is okay, since others might benefit from the answer as well.
The issue is this:
That's triggering inline editing on the test table, which is fine, but it is also being triggered by the click on the final column in the table (specifically the cross to delete the row).
Try using:
to resolve that (i.e. have the click listener for inline editing only on the columns that should be inline editable).
Allan
Super Allan!
Thanks for the quick and prompt support. I love this wonderful tool!
Velu