adding a jqgrid column that is a result of two other columns - javascript

I want to sum the column values of a jqGrid table.I have four columns in my jqGrid"SL", "Item", "Quantity", "Rate","Amount",where Amount is the result of Quantity*Rate this multiplication is not a query retrieved data.It is done inside the javascript code.Now I want to sum the amount column.Summation is showing correctly.I've checked it with an alert but when I tried to set it on footer row$grid.jqGrid('footerData', 'set', { 'amountcalculate': parseFloat(colSum)}); it is showing NAN.why is it not working.I have used footer row earlier and did summation.It worked perfectly.When I tried to add the column value which is a result of two other columns then it does not work.
Here is my code
subGrid : true,
subGridRowExpanded: function (subgridId, rowid) {
var subgridTableId = subgridId + "_t";
$("#" + subgridId).html("<table id='" + subgridTableId + "'></table>");
$("#" + subgridTableId).jqGrid({
datatype: "json",
url: "/bbbb/regfgfgfisterFgshGood /listReceivableOrderDetails?id=" + rowid,
colNames: ["SL", "Item", "Quantity", "Rate","Amount"],
colModel: [
{name: "sl", width: 40, align: 'center'},
{name: "item", width: 230, align: 'left'},
{name: "quantity", width: 100, align: 'center'},
{name: "amount", width: 100, align: 'right'},
{ name: "amountcalculate", width: 60,
formatter: function (cellvalue, options, rowObject)
{
var rq = parseFloat(rowObject[2] );
var up = parseFloat(rowObject[3] );
return parseFloat(rq * up).toFixed(2);
}
}
],
height: "100%",
rowNum: -1,
sortname: "name",
footerrow : true,
idPrefix: "s_" + rowid + "_"
});
debugger
var $grid = $("#" + subgridTableId);
var colSum = $grid.jqGrid('getCol', 'amountcalculate', false, 'sum');
alert(colSum);
$grid.jqGrid('footerData', 'set', { 'amountcalculate': parseFloat(colSum)});
},

Please include in all your questions the information about the version of jqGrid, which you use (can use) and the fork of jqGrid (free jqGrid, commercial Guriddo jqGrid JS or an old jqGrid in version <=4.7). The solution can have depend on the information.
I suppose that the origin of your problem is the usage of custom formatter without specifying the corresponding unformatter function. See the documentation.
In general, it's better to replace custom formatter to jsonmap function, which return the calculated value based on the value of tow other properties. It allows for example to combine the jsonmap function with another formatter, for example with formatter: "currency", formatter: "integer" and so on.

Related

Tabulator: how to modify local array when deleting rows?

I'm trying to build an interactive table that could be modified by the user. In my case, the original dataset is a local array of objects.
Tabulator has the buttonCross option to delete rows, but it only affects the table visuals. How can I make it find the matching object the row presents and delete it from the tabledata array?
Here's the code I'm working with:
let tabledata = [{
animal: "hippo",
color: "grey"
},
{
animal: "puma",
color: "black"
},
{
animal: "flamingo",
color: "pink"
}
];
let table = new Tabulator("#example-table", {
data: tabledata,
layout: "fitDataFill",
addRowPos: "bottom",
reactiveData: true,
headerSort: false,
columns: [ //define the table columns
{
title: "animal",
field: "animal",
editor: "input"
},
{
title: "color",
field: "color",
editor: "input"
},
{
formatter: "buttonCross",
width: 40,
align: "center",
cellClick: function (e, cell) {
cell.getRow().delete();
}
},
],
});
Codepen here.
Would really appreciate some tips on how to make this work!
Working example for tabulator
the filter function is used to remove the current item for the collection
filter Filter API.
First filter the object you don't need and then assign it to tabledata.
cellClick: function (e, cell) {
debugger;
var animalToDelete={ animal:cell.getRow().getData().animal,
color:cell.getRow().getData().color
};
var filtered=tabledata.filter(function(x){
debugger;
return x.animal!=animalToDelete.animal
&& x.color!=animalToDelete.color;
});
tabledata=filtered;
cell.getRow().delete();
}
You could also look to use tabulator in Reactive Data Mode
In this mode it will update the table in real time to match the provided data array as it is changed, and vice versa it will update the array to match the table.
To do this set the reactiveData property to true in the tables constructor object.
//create table and assign data
var table = new Tabulator("#example-table", {
reactiveData:true, //enable reactive data
data:tableData, //assign data array
columns:[
{title:"Name", field:"name"},
{title:"Age", field:"age", align:"left", formatter:"progress"},
{title:"Favourite Color", field:"col"},
{title:"Date Of Birth", field:"dob", sorter:"date", align:"center"},
]
});
It will then maintain a link with the initial data source

Distinguish between text and checkbox in jquery selector

I want to convert my table to html. I am trying to derive the data from the input text fields and not from the input checkbox fields
The following is my javascript code as can be seen in the fiddle:
$(document).ready(function(){
$('#hello').click(function(e) {
var array = [];
var headers = [];
$('#my_table tr:first-child td').each(function(index, item) {
headers[index] = $('> input[type="text"]', item).val();
});
$.each(headers, function(index, item) {
var name=item;
var data =[];
$('#my_table tr:first-child').nextAll().each(function() {
$('td:nth-child('+(index+1)+')', $(this)).each(function(index, item) {
data.push(parseInt($('> input[type="text"]', item).val()));
});
});
array.push({name: name, data:data});
});
var categories=array[0].data;
alert(categories);
array.shift();
var chart= new Highcharts.Chart({ chart: {
renderTo: 'container'
},
title: {
text: 'Monthly Average Temperature',
x: -20 //center
},
subtitle: {
text: 'Source: WorldClimate.com',
x: -20
},
xAxis: {
categories: categories
},
yAxis: {
title: {
text: 'Temperature (°C)'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
series: array
});
});
});
My code is supposed to take the first column as the xaxis. For this it is supposed to skip the checkbox column. However, the jquery selector does not appear to distinguish between both types of inputs and skip the column type. What am I supposed to do differently to achieve what I intend?
There are two main causes for this:
In the loop where you build the header you don't filter out the first column. True, the input[type="text"] selector will not give a result for the first column, but it still generates an entry in the headers array. Instead, move that input selector into the main selector so that you don't even visit the first column
In the loop where you build the array variable, you access the td by the selector td:nth-child('+(index+1)+')', but since the index values start at 0, you'll be accessing child number 1, which still is the first column. So you need to write index+2 in there.
With some other improvements (the use of map is useful for generating arrays), the following code could be used:
var headers = $('#my_table tr:first-child input[type="text"]').map(function() {
return $(this).val();
}).get();
var array = $.map(headers, function(item, index) {
var name = item;
var data = $('#my_table tr td:nth-child('+(index+2)+') input[type="text"]')
// slice(1) will skip the first row (alternative to your method)
.slice(1).map(function() {
return +($(this).val()); // unitary + will do number conversion
}).get();
return {name: name, data: data};
});
var categories = array.shift().data;
var chart= new Highcharts.Chart({ chart: {
// ... etc.
After entering some input in this updated jsfiddle, I got this result:

Javascript Datatable limit amount of characters shown in a cell

I am creating a DataTable in Javascript, which has the following properties:
var dtable = $('.ssdatatable').DataTable({
"lengthMenu": [[10, 25, 50, 100, 500], [10, 25, 50, 100, 500]],
"bProcessing": true,
"sDom": "TBflrtip",
"bServerSide": true,
"sAjaxSource": ajSource,
"iDisplayLength": 25,
"bJqueryUI": false,
"bAutoWidth": false,
//"bAutoLength": false,
//"bLengthChange": false,
"recordsFiltered": 0,
"sPaginationType": "full_numbers",
"bPaginate": true,
"sServerMethod": "POST",
"responsive": true,
"fixedHeader": true,
"buttons": [
'copy', 'excel', 'pdf'
],
"aoColumns": [
//columns
]
});
One of the particular columns is a Description, which has a LOT of text in it. The width of columns is fixed, however because of that, the height of my rows are blowing out of proportions, making page x10 of its intended size.
My question is: is there anything I can add inside the properties to make it show only N characters, and by hitting limit it would be something like:
|text textte...|
| Show More|
(I tried commented out options, did do me any good)
Or would I need to use some method or modify css?
Had the same problem - only I wanted to show all the text when the table is exported and thus only limit the text, when displayed. So based on this blog https://datatables.net/blog/2016-02-26, I further developed the code in order to allow the whole text to be shown when the table is exported.
In order to do so, I altered the code so text > 50 char is not removed, but instead wrapped in a span which is then hidden from CSS.
The function code looks like this:
function(data, type, row) {
if (type === 'display' && data != null) {
data = data.replace(/<(?:.|\\n)*?>/gm, '');
if(data.length > 50) {
return '<span class=\"show-ellipsis\">' + data.substr(0, 50) + '</span><span class=\"no-show\">' + data.substr(50) + '</span>';
} else {
return data;
}
} else {
return data;
}
}
Then from the CSS file you can add:
span.no-show{
display: none;
}
span.show-ellipsis:after{
content: "...";
}
given data:
var mydt = [{ a: 1, b: 2, c: 3, d: 4 }, { a: 5, b: 6, c: 7, d: 8 }, { a: 10, b: 12, c: 13, d: 14 }];
$("#tbl2").DataTable({
columnDefs: [{ targets:[0] }],
data: mydt, columns: [{ data: "a" }, { data: "b" }, { data: "c" }, { data: "d" }],
createdRow: function (row, data, c, d) {
// so for each row, I am pulling out the 2nd td
// and adding a title attribute from the
// data object associated with the row.
$(row).children(":nth-child(2)").attr("title", data.b)
},
and the rest
here is a working one in jfiddle https://jsfiddle.net/bindrid/wbpn7z57/7/ note that this one has data in a different format but it works (on the first name column)
// DataTable created the createRow hook to allow the row html to be updated after it was created.
-- row is the current row being created
-- data is the data object associated with the row.
createdRow: function (row, data, c, d) {
$(row) gets the tr in a jQuery object
$(row).children() gets all of the td's in the row
(":nth-child(2)") gets the 2nd td in the row. Note, this is 1 based value,not 0 based.
.attr is the jquery command that adds the "title" attribute to the td.
the "title" is missed name but too late now.
data.b matches the data structured used to populate the table.
The actual structure of this data structure is dependent on your data source so you would actually have to check it.
Hope this helps :)
In the below example code block:
Whereas "Targets": 2 indicates column index, "data":"description" points out column name that wanted to be manipulated. When we look at the render function, description column is limited to 100 characters length.
var dtable = $('.ssdatatable').DataTable({
"lengthMenu": [[10, 25, 50, 100, 500], [10, 25, 50, 100, 500]],
"bProcessing": true,
"sDom": "TBflrtip",
"bServerSide": true,
"sAjaxSource": ajSource,
"iDisplayLength": 25,
"bJqueryUI": false,
.....
{
"targets": 2,
"data":"description",
render: function(data, type, row, meta) {
if (type === 'display') {
data = typeof data === 'string' && data.length > 100 ? data.substring(0, 100) + '...' : data;
}
return data;
}
},
});

Updating Columns Dynamically - Alloy UI

I'm trying to change columns dynamically in my Alloy UI DataTable - depending on what button is selected, columns are changed depending on which data is returned.
My columns get updated, however the actual data is never included in the table. When I don't define any columns both the columns and data are returned - I of course want control of how my columns are displayed and want to set their attributes
Below is my code:
var dataTable = new Y.DataTable({ //Defining Datatable with no columns preset
editEvent: 'dblclick',
plugins: [{
cfg: {
highlightRange: false
}]
});
button.on(
'click', //On Click...
function() {
var category = $(this).attr("id"); //value retrieved from id of button selected
dataSource = new Y.DataSource.IO({source: '/searchMyData
dataSource.sendRequest({
dataType: 'json',
on: {
success: function(e) {
response = e.data.responseText;
setColumnNames(category); //Set the Columns...
data = Y.JSON.parse(response);
dataTable.set('data', data);//Then the Data
dataTable.render('#my-container');
},
failure: function() {
alert(e.error.message);
}
}
});
function setColumnNames(tabName){ //Defining Columns
var columns1 = [
{ key: 'id', label: 'ID', width: '70px' },
{ key: 'name', label: 'Name', width: '70px' }
];
var columns2 = [
{ key: 'id', label: 'ID', width: '70px' },
{ key: 'addr', label: 'Address', width: '70px' }
];
switch (category) {
case "person":
dataTable.set('columns', columns1);
break;
case "address":
dataTable.set('columns', columns2);
break;
default:
console.log('');
}
There's no issue with the data returning from the ajax request, only when it comes to loading it to the table with a new set of columns defined. I've tried the reset() method on both columns and data on each click, but no luck.
It turns out the keys returned from my request were being capitalized and included underscores (just how they're defined in the database) - I've also noticed defining the columns key is case sensitive. If I changed a single character from lower case to upper than the column would not display data.

Extjs: only show checkbox when another field has a value

i have a grid with a checkboxcolumn, all works fine but i would like to only show the checkbox if another field has a certain value. I work with version 3.3.1 but i guess that an example from another version would get me started.
If not possible, disabling the checkbox would also be fine.
Do i have to do that in a renderer or a listener and how ?
var checkColumn = new Ext.grid.CheckColumn({
header: 'Checklist OK ?',
dataIndex: 'checklist_ok',
width: 20,
align: 'center'
});
cmDiverse = new Ext.grid.ColumnModel({
defaults: {"sortable": true, "menuDisabled":false, "align":"right"},
store: storeDiverse,
columns: [
{"id":"id", "header": "id", "hidden": true, "dataIndex": "id", "width": 20},
checkColumn,
...
gridDiverse = new Ext.ux.grid.livegrid.EditorGridPanel({
id : "gridDiverse",
enableDragDrop : false,
loadMask : true,
clicksToEdit : 1,
layout :'anchor',
cm : cmDiverse,
....
You can extend your Ext.ux.grid.livegrid.EditorGridPanel like this:
Ext.extend(Ext.ux.grid.livegrid.EditorGridPanel,{
constructor:function(config){
config = Ext.apply({
cm: this.createColumnModel()
},config);
},
createColumnModel: function(){
PUT YOUR LOGIC HERE AND RETURN AN ARRAY OF COLUMNS...
}
})
Found it myself, added the following renderer to checkColumn
renderer : function(v, p, record){
var type3m = record.get('type3m');
if ((['6M','11e']).indexOf(String(type3m)) != -1){ //if the field type3m contains certain values
p.css += ' x-grid3-check-col-td';
return '<div class="x-grid3-check-col'+(v?'-on':'')+' x-grid3-cc-'+this.id+'"> </div>';
}
}

Categories

Resources