Render data from DataTables to lowercase - datatables

I need to render data returned by dataTables to lowercase. I've search the net but can't find any post on the subject. Convert "ImageName" content to lowercase before displaying. My code is:
{ data: 'ImageName', "sWidth": "20%", render : function (data, type)
{ return '<img src="' + imagepath + '' +data+'" class="WayfinderSignageImage"/>'; }
},

Related

DataTables - Responsive hiding columns on large screens

I have a problem with DataTables - I want to use the responsive add-on to hide columns on smaller screen sizes, unfortunately the responsive add-on is hiding columns on larger screen sizes when it really doesn't need to.
Here is my javascript code:
var table = $('#peopleTable').DataTable({
responsive: true,
ajax: {
dataType: 'text',
type: 'POST',
url: apiUrl,
dataSrc: function (json) {
return $.parseJSON(json);
}
},
columns: [
{
data: 'name',
responsivePriority: 1,
width: '5%',
render: function (data, type, row) {
return '<img class="icon" title="' + row.people_type + '" src="<?php echo $localPath; ?>/webimg/people-type/b/' + row.people_type_id + '.png">' + row.main_contact + ' # ' + row.name + '';
}
},
/*{
data: 'main_contact',
responsivePriority: 1,
width: '5%'
},*/
{
data: 'add1',
responsivePriority: 1,
width: '5%',
render: function (data, type, row) {
var output = [];
if (row.add1) { output.push(row.add1); }
if (row.add2) { output.push(row.add2); }
if (row.add3) { output.push(row.add3); }
if (row.town) { output.push(row.town); }
var outputStr = output.join(', ');
return '<span class="address-trunc" title="' + outputStr + '">' + outputStr + '</span>';
}
},
{
data: 'phone',
responsivePriority: 1,
width: '5%'
},
/*{
data: 'email',
responsivePriority: 1,
width: '5%',
render: function (data, type, row) {
return '' + row.email + '';
}
},*/
{
data: 'id',
orderable: false,
responsivePriority: 1,
width: '5%',
render: function (data, type, row) {
var url = '<?php echo $localPath;?>/people/person.php?id=' + row.id;
return 'View '
<?php if ($activeUser->can('delete')) { ?>
+ 'Delete'
<?php } ?>
;
}
}
]
});
As you can see I have been playing about with the code in order to make all the columns appear on a large screen size.
When I started off I had more columns in play (they are now commented out), I had all the widths adding up to 100%, and I have all the responsivePrioritys set to correct values (instead of them all being 1).
Reducing the number of columns, setting lower widths, altering responsivePrioritys - doing all of these things had no effect, on a large screen the responsive add-on was still insisting on hiding at least 1 column.
How do I stop this? I still want to use the add-on as it is very useful on smaller screens, but I don't want it force the hiding of columns when it doesn't need to.
To show you what is happening, here is a screen shot - you can see the huge almost-empty columns where there is plenty of room for another column - and yet DataTables is insisting on hiding a column behind the + symbol on the far left.
Responsive extension has many classes to configure when columns should be visible/hidden.
You could use desktop class to specify columns shown for window width greater than or equal to 1024 px.
See this example for code and demonstration.
Why not just use
var table = $('#peopleTable').DataTable({
responsive: window.innerWidth < 1000 ? true : false,
...
})
I mean simply not initialize the responsive extension when it is not needed. 1000 is just a suggestion, "larger screen sizes" is relative :)
demo -> http://jsfiddle.net/8vtqsf7z/

DataTables export PDF, Export original data from database not edited

I have one column in my table called "Info" where i have a code to render that column where if string is longer then 20 characters it will shorten it and put '...' at the end of string. Here is an example:
{
targets: 4,
"data": "info",
"render": function(data, type, row, meta) {
if(type === 'export') {
return data;
}
if (data != null) {
return type === 'display' && data.length > 20 ?
'<p data-toggle="tooltip" title="' + data + '">' + data.substr(0, 20) + '...</p>' : data;
} else {
return data;
}
}
},
Problem here is when I generate PDF I have data in that column shorten with '...', is it possible to have full data (full string) in pdf, excel etc. while having it shorten in table (column). I can always make one more column and make it invisible and then put that column in pdf. Is there any other way?
In your render function, your correctly looking to see if the type is export:
if(type === 'export') {
return data;
}
However, the type isn't export by default, even for PDFs or excels. You need to add the variable orthogonal to the export button decalaration object. This is then passed on to the render function as type
buttons: [
{
extend: 'excel',
exportOptions: { orthogonal: 'export' }
},
{
extend: 'pdf',
exportOptions: { orthogonal: 'export' }
}
]
More info on orthogonal here:
https://datatables.net/extensions/buttons/examples/html5/outputFormat-orthogonal.html

YUI3 - Autocomplete with local images

I'm trying to make an input with auto-completion but since I 'm working with emoticons need to show a picture and text on the list of recommendations
<div id="demo" class="yui3-skin-sam">
<input id="ac-input" type="text">
</div>
YUI().use('autocomplete', 'autocomplete-filters', 'autocomplete-highlighters', function (Y) {
Y.one('#ac-input').plug(Y.Plugin.AutoComplete, {
resultFilters : 'phraseMatch',
resultHighlighter: 'phraseMatch',
source : ['Alabama','Alaska','Arizona']
});
});
The output should be something like
thanks !!!
Here is a great example right from the YUI3 Documentation:
http://yuilibrary.com/yui/docs/autocomplete/ac-flickr.html?mock=true
The most important part of this code is the result formatter:
resultFormatter: function (query, results) {
return Y.Array.map(results, function (result) {
return '<div class="result">' +
'<img class="photo" src="' + getImageUrl(result) + '" alt="thumbnail">' +
'<span class="title">' + result.highlighted + '</span>' +
'</div>';
});
}
Haven't done something like that with icons etc. but I would check result formatter first and if it is not "good enough" I would try extending AutoCompleteBase. Example from YUI site:
// HTML template string that will be used for each tweet result.
var tweetTemplate =
'<div class="tweet">' +
'<div class="hd">' +
'<img src="{profile_image_url}" class="photo" ' +
'alt="Profile photo for {from_user}">' +
'</div>' +
'<div class="bd">' +
'<strong class="user">{from_user}</strong>' +
'<span class="tweet-text">{highlighted}</span>' +
'</div>' +
'<div class="ft">{created_at}</div>' +
'</div>';
// Custom formatter for tweets.
function tweetFormatter(query, results) {
// Iterate over the array of tweet result objects and return an
// array of HTML strings.
return Y.Array.map(results, function (result) {
var tweet = result.raw;
// Use string substitution to fill out the tweet template and
// return an HTML string for this result.
return Y.Lang.sub(tweetTemplate, {
created_at : tweet.created_at,
from_user : tweet.from_user,
highlighted : result.highlighted,
profile_image_url: tweet.profile_image_url
});
});
}
// Instantiate AutoComplete using the custom formatter.
Y.one('#ac-input').plug(Y.Plugin.AutoComplete, {
resultFormatter: tweetFormatter,
resultHighlighter: 'phraseMatch',
resultListLocator: 'results',
resultTextLocator: 'text',
source: 'http://search.twitter.com/search.json?q={query}&callback={callback}'
});
Both will take quite a lot of reading and experimenting, but you should be able to modify it to suit your needs...

DataTables warning: Requested unknown parameter '0' from the data source for row '0'

Does anybody please know, what is wrong with the very simple HTML file below?
I am just trying to use an array of objects as the data source for DataTables:
tests.html:
<html>
<head>
<link type="text/css" rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/redmond/jquery-ui.css">
<link type="text/css" rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.2/css/jquery.dataTables_themeroller.css">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.2/jquery.dataTables.min.js"></script>
<script type="text/javascript">
var data = [
{"Name":"UpdateBootProfile","Result":"PASS","ExecutionTime":"00:00:00","Measurement":[]},
{"Name":"NRB Boot","Result":"PASS","ExecutionTime":"00:00:50.5000000","Measurement":[{"TestName":"TOTAL_TURN_ON_TIME","Result":"PASS","Value":"50.5","LowerLimit":"NaN","UpperLimit":"NaN","ComparisonType":"nctLOG","Units":"SECONDS"}]},
{"Name":"NvMgrCommit","Result":"PASS","ExecutionTime":"00:00:00","Measurement":[]},
{"Name":"SyncNvToEFS","Result":"PASS","ExecutionTime":"00:00:01.2500000","Measurement":[]}
];
$(function() {
var testsTable = $('#tests').dataTable({
bJQueryUI: true,
aaData: data,
aoColumns: [
{ mData: 'Name' },
{ mData: 'Result' },
{ mData: 'ExecutionTime' }
]
});
});
</script>
</head>
<body>
<table id="tests">
<thead>
<tr>
<th>Name</th>
<th>Result</th>
<th>ExecutionTime</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</body>
</html>
UPDATE: Ok, I've got the answer from the author to use a newer version of DataTables or rename mData to mDataProp
For null or undefined value error, Just add this line to attributes : ,columnDefs: [ { "defaultContent": "-", "targets": "_all" } ]
Example :
oTable = $("#bigtable").dataTable({
columnDefs: [{
"defaultContent": "-",
"targets": "_all"
}]
});
The alert box will not show again, any empty values will be replaced with what you specified.
You're using an array of objects. Can you use a two dimensional array instead?
http://www.datatables.net/examples/data_sources/js_array.html
See this jsfiddle: http://jsfiddle.net/QhYse/
I used an array like this and it worked fine:
var data = [
["UpdateBootProfile","PASS","00:00:00",[]] ,
["NRB Boot","PASS","00:00:50.5000000",[{"TestName":"TOTAL_TURN_ON_TIME","Result":"PASS","Value":"50.5","LowerLimit":"NaN","UpperLimit":"NaN","ComparisonType":"nctLOG","Units":"SECONDS"}]] ,
["NvMgrCommit","PASS","00:00:00",[]] ,
["SyncNvToEFS","PASS","00:00:01.2500000",[]]
];
Edit to include array of objects
There's a possible solution from this question: jQuery DataTables fnrender with objects
This jsfiddle http://jsfiddle.net/j2C7j/ uses an array of objects. To not get the error I had to pad it with 3 blank values - less than optimal, I know. You may find a better way with fnRender, please post if you do.
var data = [
["","","", {"Name":"UpdateBootProfile","Result":"PASS","ExecutionTime":"00:00:00","Measurement":[]} ]
];
$(function() {
var testsTable = $('#tests').dataTable({
bJQueryUI: true,
aaData: data,
aoColumns: [
{ mData: 'Name', "fnRender": function( oObj ) { return oObj.aData[3].Name}},
{ mData: 'Result' ,"fnRender": function( oObj ) { return oObj.aData[3].Result }},
{ mData: 'ExecutionTime',"fnRender": function( oObj ) { return oObj.aData[3].ExecutionTime } }
]
});
});
This plagued me for over an hour.
If you're using the dataSrc option and column defs option, make sure they are in the correct locations. I had nested column defs in the ajax settings and lost way too much time figuring that out.
This is good:
This is not good:
Subtle difference, but real enough to cause hair loss.
I was having the same problem. Turns out in my case, I was missing the comma after the last column. 30 minutes of my life wasted, I will never get back!
This is a very common case in DataTables when it's not able to find the request field define in DataTable configuration.
For Example:
"aoColumns": [{
mData: 'mobile', sWidth: "149px;"
}, {
mData: 'name', sWidth: "121px;"
}, {
mData: 'productName', sWidth: "116px;"
}
}];
Here, If DataTable doesn't receive above mentioned properties. It'll generate this warning:
DataTables warning: Requested unknown parameter '0' from the data source for row '0'
To overcome this you just need to simply set a default value in "aoColumns"
For Example:
"aoColumns": [{
mData: 'mobile',sDefaultContent : '',sWidth: "149px;"
}, {
mData: 'name',sDefaultContent : '', sWidth: "121px;"
}, {
mData: 'productName',sDefaultContent : '', sWidth: "116px;"
}
}];
sDefaultContent will supress the warning.
Note: This property could be changed based on version of dataTables you are using.
Make sure that the column names are the same. They are case sensitive. Here, in my case, i got this error when the column names of my model are in capitalzed and i used all the lower case letters in the data of ajax request.
So,i resolved by matching the column names exactly the same way as the existing model names.
DataTable Binding
$("#Customers").DataTable({
ajax: {
url: "/api/customers/",
dataSrc: ""
},
columns: [
{
data: "Name",
render: function (data, type, customer) {
return "<a href='/customers/edit/" + customer.Id + "'>" + customer.Name + "</a>";
}
},
{
data: "Name"
},
{
data: "Id",
render: function (data) {
return "<button class='btn-link js-delete' data-customer-id=" + data + ">Delete</button>";
}
}
]
});
Web API Method:
public IEnumerable<Customer> GetCustomers()
{
return _context.Customers.ToList();
}
My Model:-
public class Customer
{
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
[Display(Name="Date Of Birth")]
public DateTime? BirthDate { get; set; }
public bool isSubscribedToNewsLetter { get; set; }
public MembershipType MembershipType { get; set; }
[Display(Name="Membership Type")]
[Required]
public byte MembershipTypeId { get; set; }
}
so here in my case, iam populating datatable with columns(Name,Name,Id).. iam duplicating the second column name to test.
From DataTables website:
Each cell in DataTables requests data, and when DataTables tries to
obtain data for a cell and is unable to do so, it will trigger a
warning, telling you that data is not available where it was expected
to be. The warning message is:
DataTables warning: table id={id} - Requested unknown parameter
'{parameter}' for row {row-index}
where:
{id} is replaced with the DOM id of the table that has triggered the error
{parameter} is the name of the data parameter DataTables is requesting
{row-index} is the DataTables internal row index for the rwo that has triggered the error.
So to break it down, DataTables has requested data for a given row, of
the {parameter} provided and there is no data there, or it is null or
undefined.
See this tech note on DataTables web site for more information.
I face this issue because I messed return keyword in custom rendering in Columns section
columns: [
{....
'data': function(row, type, val, meta) {
if (row.LetterStatus)
return '#CultureHelper.GetCurrentCulture()' == 'ar'? row.LetterStatus.NameInArabic: row.LetterStatus.NameInEnglish;
else row.LetterStatusID.toString();// here is the problem because I messed the Return key keyword
},
......
}
the problem in my code is because I messed the Return keyword in the else clause
so I changed it to
....
else return row.LetterStatusID.toString();// messed return keyword added
.....
In my weird scenario, I had a different column that didn't always return a value in the 'render' function. return null solved my issue.
If someone is using the new DataTables (which is awesome btw) and want to use array of objects then you can do so easily with the columns option. Refer to the following link for an excellent example on this.
DataTables with Array of Objects
I was struggling with this for the past 2 days and this solved it. I didn't wanted to switch to multi-dimensional arrays for other code reasons so was looking for a solution like this.
If you're using knockout.bindings.dataTables.js then you can edit the file and replace this line
dataTable.fnAddData(unwrappedItems);
with
if (unwrappedItems.length > 0) {
dataTable.fnAddData(unwrappedItems);
}
This has help me and i hope will help you.
it's 2022 and I just stumbled upon this problem, fortunately easy to solve.
The issue is (most probably) that your render function does not return anything useful, BUT it has to (in all cases):
columns : [
// ...
{
// wrong, no state no return value, the result is the
// warning pop up
render : function(data, type, row, meta) {
if (row.state) {
return 'State is ' + row.state
}
}
}
// ...
]
This makes it go away:
columns : [
// ...
{
// this covers all cases
render : function(data, type, row, meta) {
if (row.state) {
return 'State is ' + row.state
}
// in this example make sure that at least
// something is returned
return '';
}
}
// ...
]
Alternatively you can add defaultContent : '' to you column definition, same effect.

ExtJs 4.1 TreeGrid treecolumn custom renderer

Is it possible to merge 2 columns in TreeGrid, when one of them is xtype 'treecolumn'?
For now I have 2 separate columns, one is standard treecolumn, second is templatecolumn with custom template (basically an image)
What I would like to get should look like this:
So that second column content is added to first but aligned to right.
I have no idea how to even start with that kind of renderer :(
This is code for my columns so far:
{
xtype : 'treecolumn',
text : 'DziaƂ/Pracownik',
width : 200,
sortable : true,
hideable: false,
dataIndex : 'Name',
renderer: function (v, m, r) {
if(r.get('leaf')==true)
m.tdAttr = 'data-qtip="<img src=services/Images.ashx?login='+r.get('login')+' width=60px height=60px>"';
return v;
}
},
{
text : 'Zdj',
width: 40,
align : 'center',
dataIndex : 'Name',
sortable : false,
resizable: false,
xtype : 'templatecolumn',
tpl : imgTpl
},
...
var imgTpl = Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<tpl if="values.leaf == true">',
'<img src="services/Images.ashx?login={login}" width="25px" height="25px"/>',
'</tpl>',
'</tpl>'
);
I will really be gratefully for any hints on how to merge those 2 columns.
Here is what I ended up doing with that:
renderer:function (value, meta, record) {
var tasks = record.get("tasks"),
tpl = this.taskImgTpl,
type, qtip;
if (tasks && tasks.length >0){
Ext.each(tasks, function(task){
if(task.refType) {
type = task.refType;
} else {
type = task.type.name;
}
qtip = Ext.String.format('Status: {0} Assignee: {1} %Complete: {2}',task.state,task.assignee||'',task.pctComplete);
value += tpl.apply([type, qtip]);
},this);
}
return value;
}
And the image template that is being inserted is :
taskImgTpl:new Ext.XTemplate(" <img class='{0} h16' width='16px' data-qtitle='{0}' data-qwidth='120' data-qtip='{1}'/>")
where h16 is a class that gives height:16px, and the dynamically inserted class carries a background image (16x16) of whatever the type of object is being displayed. You of course can just set the src attribute instead.
What I have done is instead using template I've used renderer, so my column now looks like this:
{
xtype : 'treecolumn',
text : 'Employee',
width : 200,
sortable : true,
hideable : false,
dataIndex : 'Name',
renderer : function(v, m, r) {
if (r.get('leaf')) {
return '<div style="float: left">'
+ r.get('Name')
+ '</div><img data-qtip="<img src=services/Images.ashx?login='
+ r.get('login')
+ ' width=60px height=60px/>" src="services/Images.ashx?login='
+ r.get('login')
+ '" width="25px" height="25px" style="float: right; margin-right: 5px"/>';
}
return '<div style="float: left">' + r.get('Name') + '</div>';
}
}
If element is leaf then I display extra image in the right of my column + I've added bigger image after rollover.
To have this working I had to change some css inside ext-all.css:
.x-grid-with-row-lines .x-tree-icon{margin-top:1px; float: left}
.x-grid-with-row-lines .x-tree-elbow,.x-grid-with-row-lines .x-tree-elbow-end,.x-grid-with-row-lines .x-tree-elbow-plus,.x-grid-with-row-lines .x-tree-elbow-end-plus,.x-grid-with-row-lines .x-tree-elbow-empty,.x-grid-with-row-lines .x-tree-elbow-line{height:19px;background-position:0 -1px; float: left}
I had to add float:left to all images that are displayed in that cell:
x-tree-elbow
x-tree-elbow-end
x-tree-elbow-plus
x-tree-icon
I know that this can be optimised a lot, but for me it works fine. If some ExtJS guru could tweak it to work better then you're welcome :)