Adding more than one value to a single td in DataTables? - javascript

I am trying to add information to Datatables via text input. Normally, you add to DataTables with fnAddData, like so:
$('.home').dataTable().fnAddData([
$("#fName").val(),
$("#lName").val()
]);
but the issue is that I need the values from both of these inputs in the same td, not different tds. Something along the lines of:
$('td:first').text($("#fName").val() + ' ' + $("#lName").val());
...I just don't know how to go about it properly to append to DataTables. You can see that I have the information adding to the table, but this does not append the pagination and isn't correctly adding to DataTables. Any ideas? Thanks in advance.
http://jsfiddle.net/Z85QC/3/

You can join the values of the first and last name as the first array item passed to the fnAddData method. Each array item represents a column in the table.
$('#example').dataTable().fnAddData([
$("#fName").val() + $("#lName").val(),
$("#email").val(),
$("#company").val() + '<br>' + $('#address').val()
]);
See working version here: http://jsfiddle.net/Z85QC/4/

May I recommend a different approach using javascript arrays?
From your sample, the HTML table becomes:
<table cellpadding="0" cellspacing="0" border="0" class="display" id="example"></table>
You need some css rules
td.address
{
white-space: pre
}
And the code:
var thedata = [
{
name: "John Smith",
email: "jsmith#company.com",
address: "Company\n123 Seseme Street\nHouston, TX 77388 USA"
},
{
name: "Jane Doe",
email: "jdoe#company.com",
address: "Company\n123 Seseme Street\nHouston, TX 77388 USA"
}
];
var thetable = $('#example').dataTable({
aaData: thedata,
aoColumns: [
{ sTitle: "Name", mData: "name" },
{ sTitle: "Email", mData: "email" },
{ sTitle: "Address", mData: "address", sClass: "address"}
]
});
$('#addRow').click(function () {
thetable.fnAddData({
name: $("#fName").val() + ' ' + $("#lName").val(),
email: $("#email").val(),
address: $("#company").val() + '\n' + $("#address").val()
});
});
Note that you could create a different object and use a render function for each column mergin some data, but for an answer, I think this is enough.

Related

datatables sorting data with mix numbers and letters

Updated with jsfiddle: https://jsfiddle.net/pnnorhtg/
I have a data table and I am having a difficult time initializing the 'numbers with html' data tables plug-in https://datatables.net/plug-ins/sorting/num-html.
It's initially sorted on 'Count' DESC. However once I execute my function that modifies and appends html to each of the cell in that column it is no longer sortable.
Based on my research this plug-in should be able to fix this but I am having no luck.
This is my data:
var preHtmlData = [{
Brand: "Toyota",
Count: 33423,
GBV: 242445
}, {
Brand: "Ford",
Count: 23558,
GBV: 334343
}, {
Brand: "Honda",
Count: 9466,
GBV: 933455
}];
This is my function that goes through and adds html text to the value based on the key:
//adding text next to Count
function updateItemCount(preHtmlData) {
for(var key in preHtmlData) {
var value = preHtmlData[key];
console.log(value)
if (value.Brand == 'Toyota') {
value.Count = value.Count + ' <div style="font-size: 10px;margin-top: -5px">Toyota Purchases</div>';
} else if (value.Brand == 'Ford') {
value.Count = value.Count + ' <div style="font-size: 10px;margin-top: -5px">Ford Purchases</div>';
} else if (value.LOB == 'Honda') {
value.Count = value.Count + ' <div style="font-size: 10px;margin-top: -5px">Honda Purchases</div>';
}
}
}
This is what where I am initializing table:
summary_data_table = $('#resultsTable').DataTable({
"bSort": true,
"destory": true,
"data": data,
"searching": false,
"paging": false,
"order": [
[aryJSONColTable.length - 1, "desc"]
],
"dom": '<"top">t<"bottom"><"clear">',
"columnDefs": aryJSONColTable,
[
{ type: 'natural-nohtml', targets: 5 }
]
"initComplete": function(settings, json) {
$("#resultsTable").show();
}
});
I've added the plug-in and constructed my code as per the documentation, I have a feeling its some how I've defined my columnDefs, but I need it to execute aryJSONColTable and the natural sorting.
UPDATE
As seen from your fiddle, you can overcome this problem by placing an order type("type":"natural") inside your custom properties that you pass on to columnDefs
customParams = {
"targets": keys.length - 1,
"sTitle": "Item Count",
"type":"natural"
}
Please see the updated fiddle for the solution https://jsfiddle.net/pnnorhtg/1/

How to add array items in javascript?

In a wordpress plugin, there is a field box called 'data' where I can add code for it to pull, below in the code where it says 'data =' that is me referencing the box. In the box:
What I put in the field box entitled 'data':
{
contacts: [
{ name: "Name 1", email: "email1#test.com" },
{ name: "Name 2", email: "email2#test.com" }
]
};
This is what I put in the global field box, for it to apply to everything.
function (jQueryPopoverObj, mapObject, mapsvgInstance) {
// "this" = clicked mapObject
if(this.mapsvg_type == "region"){
return '<b>'+this.id+'</b>' +
this.data.contacts.map(function(contact) {
return contact.name + '<br>' +
'' + contact.email + ''
}).join('<br>');
} else if (this.mapsvg_type == "marker"){
return 'Marker - <b>'+this.id+'</b>, contact: '+this.data.email;
}
}
I want to also add { seat: "County Seat"} to the data portion and add it in the function.
I tried adding a line in the contacts, and then adding + '<br>' + contact.seat, after return contact.name, with no luck. Basically when it does the popover (which it pulls from global function for the template and the information from the data field box), I want it to have the CountySeat under the County Name (e.g. the County Seat for Harris County is Houston, so it would have Houston under Harris County).
Example of Lubbock County without the City name under it
var data = {
contacts: [
{ name: "Name 1", email: "email1#test.com" },
{ name: "Name 2", email: "email2#test.com" }
]
}
To add a new property seat you can simply do this-
data["seat"] = "County Seat"
or
data.seat = "County Seat"
JSFiddle
It looks like you want to set the seat assignment on the contact? You'd have to get the contact from the array, looping through each one and figuring out the one you want to use, then do contact.seat = "XYZ", which will add a seat property to the contact object. You can then use contact.seat in the string output but you have to null check it because it may be null. To help with that, I'd recommend defaulting it to an empty string like:
data = {
contacts: [
{ name: "Name 1", email: "email1#test.com", seat: "" },
{ name: "Name 2", email: "email2#test.com", seat: "" }
]
}
And then change it when it is assigned.

Javascript library for table rendering

I need to show an array of objects in the table like representation. Table has columns with the properties, and when clicked on the column it should show more data inside the table. It should be sortable.
Is there a JS library that could do this, so I dont have to write this from scratch?
Please see the attached image with the JSON object.
When the user clicks on Ana, additional row is inserted.
I created the demo https://jsfiddle.net/OlegKi/kc2537ty/1/ which demonstrates the usage of free jqGrid with subgrids. It displays the results like
after the user clicks on the "+" icon in the second line.
The corresponding code you can find below
var mydata = [
{ id: 10, name: "John", lname: "Smith", age: 31, loc: { location: "North America", city: "Seattle", country: "US" } },
{ id: 20, name: "Ana", lname: "Maria", age: 43, loc: { location: "Europe", city: "London", country: "UK" } }
];
$("#grid").jqGrid({
data: mydata,
colModel: [
{ name: "name", label: "Name" },
{ name: "lname", label: "Last name" },
{ name: "age", label: "Age", template: "integer", align: "center" }
],
cmTemplate: { align: "center", width: 150 },
sortname: "age",
iconSet: "fontAwesome",
subGrid: true,
subGridRowExpanded: function (subgridDivId, rowid) {
var $subgrid = $("<table id='" + subgridDivId + "_t'></table>"),
subgridData = [$(this).jqGrid("getLocalRow", rowid).loc];
$("#" + subgridDivId).append($subgrid);
$subgrid.jqGrid({
idPrefix: rowid + "_",
data: subgridData,
colModel: [
{ name: "location", label: "Localtion" },
{ name: "city", label: "City" },
{ name: "country", label: "Country" }
],
cmTemplate: { align: "center" },
iconSet: "fontAwesome",
autowidth: true
});
}
});
Small comments to the code. Free jqGrid saves all properties of input data in data parameter. I added id property to every item of input data. It's not mandatory, but it could be helpful if you would add more functionality to the grid. See the introduction for more details.
The columns are sortable based on the type of the data specified by sorttype property of colModel. To simplify usage some standard types of data free jqGrid provides some standard templates which are shortcurts for some set of settings. I used template: "integer" in the demo, but you could replace it to sorttype: "integer" if only sorting by integer functionality is important.
If the user click on "+" icon to expand the subgrid then jqGrid inserts new row and creates the div for the data part of the subgrid. You can replace subGridRowExpanded from above example to the following
subGridRowExpanded: function (subgridDivId) {
$("#" + subgridDivId).html("<em>simple subgrid data</em>");
}
to understand what I mean. The unique id of the div will be the first parameter of the callback. One can create any common HTML content in the subgrid. Thus one can create empty <table>, append it to the subgrid div and
then convert the table to the subgrid.
To access to the item of data, which corresponds to the expanding row one can use $(this).jqGrid("getLocalRow", rowid). The return data is the item of original data. It has loc property which we need. To be able to use the data as input for jqGrid we create array with the element. I's mostly all, what one have to know to understand how the above code works.
You can add call of .jqGrid("filterToolbar") to be able to filter the data or to add pager: true (or toppager: true, or both) to have the pager and to use rowNum: 5 to specify the number of rows in the page. In the way you can load relatively large set of data in the grid and the user can use local paging, sorting and filtering. See the demo which shows the performance of loading, sorting and filtering of the local grid with 4000 rows and another one with 40000 rows. All works pretty quickly if one uses local paging and not displays all the data at once.
I use datatables.net for all my "more complex than lists"-tables. I It's a very well kept library with loads of features and great flexibility.
In the "con" column I would say that it's so complex that it probably has quite a steep learning curve. Although the documentation is great so there is always hope for most problems.

How to put multiple data in a datatable column?

I'm using Datatables to represent data from a JSON.
My JSON is as follows:
[{"name": "John Doe", "email": "john#gmail.com", "address" : "blah"}]
In Datatables I can easily show these 3 pieces of info in 3 diff columns using the following:
columnDefs = [
{ "mData": "name", "aTargets":[0] },
{ "mData": "email", "aTargets":[1] },
{ "mData": "address", "aTargets":[2] }
];
But the problem is that I want to show "name" and "email" in 1st column and then "address" in the 2nd column.
How can I do that? Please guide.
to make it more short, you can write it like this
"aoColumns": [
{ "mData": "i_id" },
{ "mData": "i_name" },
{ "mData": function (data, type, dataToSet) {
return data.i_id + "<br/>" + data.i_name;
}}
],
and the result
columnDefs = [
{
data: {name : "name", email : "email", address : "address"},
mRender : function(data, type, full) {
return data.name+' '+data.email+' '+data.address;
}
}
];
The above code can render multiple data in a column of a datatable.
Rather than putting either the name or e-mail in the first column in the column definition, you can use a function to get and print whatever data you want. See the mData section on this page for more details: https://datatables.net/usage/columns. In my example below I use aoColumns because I tested my answer that way; but in the link referenced they used aoColumnDefs and provide elaboration on the type and dataToSet fields. This approach should hopefully help anyone reading this answer whether you use aoColumns or aoColumnDefs.
For example, using aoColumns rather than aoColumnDefs:
aoColumns = [
{ "mData": getNameAndEmail },
{ "mData": "address" }
];
Then define the getNameAndEmail function in JavaScript scope which takes three parameters: the data passed back, the type of action on the data, and if the type is "set" then the data to set.
function getNameAndEmail(data, type, dataToSet) {
return data.name + "<br>" + data.email;
}
[You can use syntax like this:
It worked for me.]
"columnDefs":[{
"targets":0,//column index
"data":"first_name",
"render":function(data,type,row){
return data+' '+row['last_name'];
}
}]
[thanks]

Loading Flexigrid for jQuery with JSON String

I am trying to load the Flexigrid by using a JSON String which is returned by a WCF Service.
My Service has a public string GetContacts(string CustomerID) method and it returns a Json string.
That JSON string is created from a List object by using
System.Web.Script.Serialization.JavaScriptSerializer class. So, my aim is to bind the JSON string to the my Flexigrid as objects. I convert the web service result to objects using
var customer = eval("("+result+")");
The result is the JSON string being returned from service. Is there any way to bind customer objects to Flexigrid?
Flexigrid requires a format as follows in json
EDIT Thanks to EAMann for the format update.
total: (no of rec)
page : (page no)
rows : [{cell: [ (col1 value) , (col2 value) ,.. ] },
{cell: [ (col1 value) , (col2 value) ,.. ] }]
in order to bind the data to the grid i prefer sending the data across the wire and then formatting it on the client, but thats just me heres an example
function formatCustomerResults(Customers) {
var rows = Array();
for (i = 0; i < Customers.length; i++) {
var item = Customers[i];
//Do something here with the link
var link = "alert('opening item " + item.DealGuid + "');"
rows.push({
cell: [item.DealId,
item.Created,
item.CurrentStatus,
item.LastNote,
'<a href="javascript:void(0);" onclick="' + link + '" >view</a>'
]
});
}
return {
total: Customers.length,
page: 1,
rows: rows
};
}
and then all you need is
$("#FlexTable").flexAddData(formatCustomerResults(eval(data)));
ps this last bit is jquery syntax
almog.ori's answer is almost perfect. In fact, that's just about how I had built things before trying to Google the solution. One exception, though.
The JSON object should be:
total: (no of rec),
page : (page no),
rows : [{cell: [ (col1 value) , (col2 value) ,.. ] },
{cell: [ (col1 value) , (col2 value) ,.. ] }]
If you neglect the array format of the rows element, you'll end up choking Flexigrid and throwing all sorts of errors. But I've verified that this works flawlessly as long as you remember which parts of the script take JSON objects and which parts take arrays of JSON objects.
This is an older post but I thought I would add another way to use the excellent script provided by almog.ori.
The OP said that his data was being returned from a WCF service. If you mark the operation contract body style as bare you can use the preProcess property to add your formatCustomerResults (or other function) function to initially load the grid.
Like this:
$("#gridContainer").flexigrid({
url: '/YourService.svc/..',
method: 'GET',
dataType: 'json',
preProcess: formatCustomerResults,
...
});
function formatCustomerResults(data){
...
Hope this helps someone.
Make sure also that you are using the correct HTTP method, default is POST
To use GET:
$("#gridContainer").flexigrid({
url: '/json/files.json',
method: 'GET',
dataType: 'json',
...
preProcess solution by nameEqualsPNamePrubeGoldberg works perfect.
This is how my custom function for preProcess looks like.
var rows = Array();
$.each(data.rows,function(i,row){
rows.push({id:row.val1, cell:[row.val2,row.val3]});
});
return {
total:data.total,
page:data.page,
rows:rows
};
I recommend you to follow this sample to parse your JSON code and make requests to server:
Step 1: Parse using a function
function parsedForm(json)
{
var h = "";
if (json.post.val1)
h += "<b>Value 1</b>: " + json.post.val1 + "<br />";
h += "<b>Value 2</b>: " + json.post.val2 + "<br />";
h += "<b>Value 3</b>: " + json.post.val3 + "<br />";
if (json.post.val4)
h += "<b>Value 4</b>: " + json.post.val4 + "<br />";
$('#fdata').empty().html(h);
$('.formdata').slideDown();
return json;
}
Step 2: The flexigrid view code
$("#flex1").flexigrid({
url: 'post2.php',
dataType: 'json',
colModel : [
{display: 'ISO', name : 'iso', width : 40, sortable : true, align: 'center'},
{display: 'Name', name : 'name', width : 180, sortable : true, align: 'left'},
{display: 'Printable Name', name : 'printable_name', width : 120, sortable : true, align: 'left'},
{display: 'ISO3', name : 'iso3', width : 130, sortable : true, align: 'left', hide: true},
{display: 'Number Code', name : 'numcode', width : 80, sortable : true, align: 'right'}
],
searchitems : [
{display: 'ISO', name : 'iso'},
{display: 'Name', name : 'name', isdefault: true}
],
sortname: "iso",
sortorder: "asc",
usepager: true,
title: 'Countries',
useRp: true,
rp: 15,
showTableToggleBtn: true,
width: 700,
onSubmit: addFormData,
preProcess: parsedForm,
height: 200
});
Step 3: Additonally, you can validate or serialize the data to request server
function addFormData(){
//passing a form object to serializeArray will get the valid data from all the objects, but, if the you pass a non-form object, you have to specify the input elements that the data will come from
var dt = $('#sform').serializeArray();
$("#flex1").flexOptions({params: dt});
return true;
}
$('#sform').submit(function (){
$('#flex1').flexOptions({newp: 1}).flexReload();
return false;
});
I hope it will help!
Make sure you have the dataType option set to json.
$('#gridContainer').flexigrid({
singleSelect: true,
showToggleBtn: false,
dataType: 'json'
});
I believe the latest flex code broke the solution using preProcess.
addData: function (data) { //parse data
if (p.dataType == 'json') {
data = $.extend({rows: [], page: 0, total: 0}, data);
}
if (p.preProcess) {
data = p.preProcess(data);
}
You need to flip it so that the preProcess if comes before the type JSON if. Otherwise the function listed as an answer does not work properly.
It's old, I know... But here is an example of json that works:
{
"total": 5,
"page": "1",
"rows": [
{"cell": [1, "asd", "dsa", "2013-07-30"]},
{"cell": [2, "asd", "dsa", "2013-07-30"]},
{"cell": [3, "asd", "dsa", "2013-07-30"]},
{"cell": [4, "asd", "dsa", "2013-07-30"]},
{"cell": [5, "asd", "dsa", "2013-07-30"]}
]
}
(5 results in total; first page (they are NOT zero-based); 5 lines of data, each containing { ID, "asd", "dsa", "a date" } )
Try to make total your first element in you JSON string like this.
`{"total" : 2,"page":1,"rows":[ {"cell" : ["226 CLAVEN LN", "312"]},{"cell" : ["1377 FAIRFAX PIKE","280"]}]}`

Categories