columns.render
columns.render
I have a table which has two columns where the data is serialized. I use a custom function to unserialize the data, and when the table loads all is as it should be. But when I submit an edit I encounter a problem. The database is updated but the edit for doesn't disappear and the spinner displays forever as if the form is waiting for something. I can see that the ajax call returns a correctly formatted json so I am assuming that the render function doesn't like something. (The form works as expected if I populate the field without using render). Does anyone see anything wrong with what I'm doing?
This is the javascript:
function unserialize(data) {
// discuss at: http://phpjs.org/functions/unserialize/
// original by: Arpad Ray (mailto:arpad@php.net)
// improved by: Pedro Tainha (http://www.pedrotainha.com)
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: Chris
// improved by: James
// improved by: Le Torbi
// improved by: Eli Skeggs
// bugfixed by: dptr1988
// bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// revised by: d3x
// input by: Brett Zamir (http://brett-zamir.me)
// input by: Martin (http://www.erlenwiese.de/)
// input by: kilops
// input by: Jaroslaw Czarniak
// note: We feel the main purpose of this function should be to ease the transport of data between php & js
// note: Aiming for PHP-compatibility, we have to translate objects to arrays
// example 1: unserialize('a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}');
// returns 1: ['Kevin', 'van', 'Zonneveld']
// example 2: unserialize('a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}');
// returns 2: {firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'}
"use strict";
var utf8Overhead = function(chr) {
// http://phpjs.org/functions/unserialize:571#comment_95906
var code = chr.charCodeAt(0);
if ( code < 0x0080
|| 0x00A0 <= code && code <= 0x00FF
|| [338,339,352,353,376,402,8211,8212,8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8364,8482].indexOf(code)!=-1)
{
return 0;
}
if (code < 0x0800) {
return 1;
}
return 2;
};
var read_until = function(data, offset, stopchr) {
var i = 2,
buf = [],
chr = data.slice(offset, offset + 1);
while (chr != stopchr) {
if ((i + offset) > data.length) {
}
buf.push(chr);
chr = data.slice(offset + (i - 1), offset + i);
i += 1;
}
return [buf.length, buf.join('')];
};
var read_chrs = function(data, offset, length) {
var i, chr, buf;
buf = [];
for (i = 0; i < length; i++) {
chr = data.slice(offset + (i - 1), offset + i);
buf.push(chr);
length -= utf8Overhead(chr);
}
return [buf.length, buf.join('')];
};
var _unserialize = function(data, offset) {
var dtype, dataoffset, keyandchrs, keys, contig,
length, array, readdata, readData, ccount,
stringlength, i, key, kprops, kchrs, vprops,
vchrs, value, chrs = 0,
typeconvert = function(x) {
return x;
};
if (!offset) {
offset = 0;
}
dtype = (data.slice(offset, offset + 1))
.toLowerCase();
dataoffset = offset + 2;
switch (dtype) {
case 'i':
typeconvert = function(x) {
return parseInt(x, 10);
};
readData = read_until(data, dataoffset, ';');
chrs = readData[0];
readdata = readData[1];
dataoffset += chrs + 1;
break;
case 'b':
typeconvert = function(x) {
return parseInt(x, 10) !== 0;
};
readData = read_until(data, dataoffset, ';');
chrs = readData[0];
readdata = readData[1];
dataoffset += chrs + 1;
break;
case 'd':
typeconvert = function(x) {
return parseFloat(x);
};
readData = read_until(data, dataoffset, ';');
chrs = readData[0];
readdata = readData[1];
dataoffset += chrs + 1;
break;
case 'n':
readdata = null;
break;
case 's':
ccount = read_until(data, dataoffset, ':');
chrs = ccount[0];
stringlength = ccount[1];
dataoffset += chrs + 2;
readData = read_chrs(data, dataoffset + 1, parseInt(stringlength, 10));
chrs = readData[0];
readdata = readData[1];
dataoffset += chrs + 2;
if (chrs != parseInt(stringlength, 10) && chrs != readdata.length) {
}
break;
case 'a':
readdata = {};
keyandchrs = read_until(data, dataoffset, ':');
chrs = keyandchrs[0];
keys = keyandchrs[1];
dataoffset += chrs + 2;
length = parseInt(keys, 10);
contig = true;
for (i = 0; i < length; i++) {
kprops = _unserialize(data, dataoffset);
kchrs = kprops[1];
key = kprops[2];
dataoffset += kchrs;
vprops = _unserialize(data, dataoffset);
vchrs = vprops[1];
value = vprops[2];
dataoffset += vchrs;
if (key !== i)
var contig = false;
readdata[key] = value;
}
if (contig) {
array = new Array(length);
for (i = 0; i < length; i++)
array[i] = readdata[i];
readdata = array;
}
dataoffset += 1;
break;
default:
break;
}
return [dtype, dataoffset - offset, typeconvert(readdata)];
};
return _unserialize((data + ''), 0)[2];
}
var editor; // use a global for the submit and return data rendering in the examples
$(document).ready(function()
{
"use strict";
editor = new $.fn.dataTable.Editor
(
{
table: "#example",
fields:
[
{
label: "First Name:",
name: "m_first_name.meta_value"
},
{
label: "Last Name:",
name: "m_last_name.meta_value"
},
{
label: "Auto EOT:",
name: "m_auto_eot_time.meta_value"
} ],
ajax:
{
edit: "edit-lastname.php?id=_id_"
}
}
);
$('#example').DataTable
(
{
dom: "Bfrtip",
ajax: "users.php",
type: 'POST',
columns:
[
{ data: "ul.ID", className: "dt-body-center" },
{
data: "m_user_capabilities.meta_value",
className: "dt-body-center",
render : function ( data )
{
var $user_capabilities = unserialize( data );
var $user_level = 'Undefined';
if ($user_capabilities.subscriber)
{ // a whole series of tests go here
return $user_level;
}
},
{ data: "m_first_name.meta_value", className: "dt-body-center" },
{ data: "m_last_name.meta_value", className: "dt-body-center" },
{
data: "m_custom_fields.meta_value",
className: "dt-body-center",
render : function ( data )
{
var $business_name = unserialize( data ).business_name;
if ($business_name === undefined || $business_name === null)
{
return '';
}
else
{
return $business_name;
}
}
},
{ data: "m_subscriber_id.meta_value", className: "dt-body-center" },
{ data: "m_auto_eot_time.meta_value" , editField: "m_auto_eot_time.meta_value", className: "dt-body-center" }
],
select: true,
buttons:
[
{ extend: "edit", editor: editor }
]
}
);
});
I can see the JS throws an uncaught exception: out of memory.
Any help would be much appreciated.
This question has an accepted answers - jump to answer
Answers
I have answered my question. The render function does fire once a form is successfully submitted and processed so you need to make sure the data that is being returned to it is identical in format / type to that when the table was first drawn, or have the function called when rendering handle all possible datatypes that it may encounter.
Hi,
Thanks for posting back (nice unserialise function btw!). You are absolutely correct - you need to use the same data format in the edit request return as the DataTable is feed when loading data.
I hope to be able to relax that somewhat in future.
Regards,
Allan