Slickgrid: Multiple Grouping with dynamic Parameters - javascript

I am working on SlickGrid JS plugin. And i want to dynamically group the Grid/Table based on the table header. How should I pass the parameters [getter,formatter, aggregators] dynamically
without hard coding like this
dataView.setGrouping([
{
getter : "department",
collapsed : false,
formatter : function(g){
return g.value;
},
comparer : groupComparer
},{
getter : "faculty",
collapsed : false,
formatter : function(g){
return g.value;
},
comparer : groupComparer
}
]);
Is it possible to use any looping statements to generate Array of parameters

I have tried much, and found this solution
arr=["department","faculty"]; //Dynamically generated array having titles to group
var ar = []; //empty array to push parameters
for(i = 0; i < arr.length; i++)
{
ar[i] = {
getter: arr[i],
formatter: function (g) {
return ": " + g.value + " <span style='color:green'>(" + g.count + " items)</span>";
},
aggregators: [
new Slick.Data.Aggregators.Avg("percentComplete"),
new Slick.Data.Aggregators.Sum("cost")
],
aggregateCollapsed: false,
lazyTotalsCalculation: false
};
}
dataView.setGrouping(ar);

Related

Altering array in .then statement (javascript)

In a double for loop I am looping through different values where I test if specific value returns an error. Predefined function returns promise and it is all okay, if I need it once. But I need a way to store all errors (errors array) and all correct states (corrects array) and hardware I am using does not allow dynamically adding text to screen so I am using arrays. But i cannot find a way to do it in .then block. I was searching for a solution online but could not find one that would solve my problem.
for (var i = 0; i < idarray.length; i++) {
type = idarray[i];
for (var j = 0; j < maxValues[i]; j++) {
//console.log("Type: ",type);
//here i send new command with type and value
var sethbt = myLibrary.NewCommand(uuid, "Param", {
"Data": [{
"Type": type, //number
"Control": 1,
"Value": j.toString() //string
}]
})
//here i read the value of type
var hbt = myLibrary.NewCommand(uuid, "Param", {
"Data": [{
"Type": type,
"Control": 0,
"Value": ""
}]
})
//hbt returns a promise where i get the value, if control==2 it is error, otherwise
//it is ok
hbt.then(function(data) {
obj = JSON.parse(data);
if (obj[0].Control == 2) {
var text = "ERROR: Type: \"" + obj[0].Type + "\" --> Value:\"" + obj[0].Value + "\"";
//here i want to add error to array of errors, but change is not seen
//out of .then block
errors.push(text);
} else {
corrects.push("OK: Type: \"" + obj[0].Type + "\" --> Value:\"" + obj[0].Value + "\"");
}
});
}

How to add Rowspan in JQuery datatables

Im using Jquery datatables to construct a table.
My requirement is like below
This is not a static table, and we are rendering it using json data. Here I'm, rendering the rows dynamically using "aoColumns".
Is there any way to use rowspan so that the cells (1,2,David,Alex) can be spanned.
Does datatables support this kind of table ?
Datatables does not support this kind of grouping out of the box.
But, as in many cases, there is a plugin available.
It is called RowsGroup and is located here: Datatables Forums. A live example is also included.
If you change the JS part in this example to the below you will have your desired output presented to you in the output window.
$(document).ready( function () {
var data = [
['1', 'David', 'Maths', '80'],
['1', 'David', 'Physics', '90'],
['1', 'David', 'Computers', '70'],
['2', 'Alex', 'Maths', '80'],
['2', 'Alex', 'Physics', '70'],
['2', 'Alex', 'Computers', '90'],
];
var table = $('#example').DataTable({
columns: [
{
name: 'first',
title: 'ID',
},
{
name: 'second',
title: 'Name',
},
{
title: 'Subject',
},
{
title: 'Marks',
},
],
data: data,
rowsGroup: [
'first:name',
'second:name'
],
pageLength: '20',
});
} );
Here is a screenshot of the result:
I tried the RowsGroup plugin, but it achieves this just by hijacking the DataTables sort mechanism. If you tell it to group a given column, what it does for you is basically to apply a sort to that column that you can't turn off. So, if you want to sort by another column, you can't. That didn't work in my application.
Instead, here's a working fiddle for a recipe that allows you to achieve this result:
https://jsfiddle.net/bwDialogs/fscaos2n
The basic idea is to flatten all of your multi-row data into a single row. Content in your 2nd, 3rd, etc. rows are stored as a hidden <script> template tag within your first row.
It works by using DataTables' drawCallback function to manipulate the DOM once DataTables has rendered it, without confusing DataTables by having to try parsing rowspan cell content.
Since this modifies the DOM after DataTables has done its magic, your multi-row sections will stick together even with pagination, searching, and sorting.
Cheers.
add a below code and modify according to your requirement
$(window).on("load",function() {
MakeRows();
addRowspan();
$(".paginate_button").on("click", function() {
MakeRows();
addRowspan();
});
});
function MakeRows() {
var tmp_tbl = $("#dashboardDetails");
var _l = tmp_tbl.find("tr");
var _td = "",_t_td = "", old_txt = "",_t_txt = ""; _tr_count = 1;_tr_countadd = 1;
for(i = 0;i< _l.length; i ++) {
_t_td = tmp_tbl.find("tr").eq(i).find("td").eq(0).find("span");
_t_txt = $(_t_td).text();
_t_txt = _t_txt.replace(/\//,"_");_t_txt = _t_txt.replace(/\//,"_");
if (_t_txt.length > 0) {
if(_t_txt != old_txt) {
if($(_l).eq(i).hasClass(_t_txt) == false) {
_tr_count = 1;_tr_countadd = 1;
$(_l).eq(i).addClass("" + _t_txt + "").addClass(_t_txt + "_" + i);
}
old_txt = _t_txt;
} else {
_tr_count = _tr_count + 1;
if (_tr_countadd == 1) {
$(_l).eq(i).addClass("" + _t_txt + "").addClass(_t_txt + "_" + i)
.addClass("hiddenClass").addClass("maintr").attr("trcount", _tr_count).attr("addedtrcount", "maintr");
_tr_countadd = _tr_countadd + 1;
} else {
$(_l).eq(i).addClass("" + _t_txt + "").addClass(_t_txt + "_" + i)
.addClass("hiddenClass").attr("trcount", _tr_count)
}
}
}
_t_td = "";
}
}
function addRowspan() {
var t_txt = "";
var _alltrmain = $(".maintr");
var _h_td = ["0","10","11","12","13"];
for (i = 0; i <= _alltrmain.length; i ++) {
for (j = 0; j <= _h_td.length; j ++) {
t_txt = $(_alltrmain).eq(i).attr("trcount");
$(_alltrmain).eq(i).prev().find("td").eq(_h_td[j]).attr("rowspan", t_txt);
}
}
}

JSON-Object as string: Use of concat(), eval() and/or JSON.parse()?

What I want to do: I want to display a diagram using Highcharts and the best code style.
Problem: My code is unreadable / hard to debug because I store it within variables.
Okay I have a Javascript-Object containing all the information I need for later use (categories, y axis value and the series itself which is split into positive, neutral and negative).
var testDia =
{
name : 'Testname',
'chartCategories': ['Golf', 'Polo', 'Passat'],
'chartSeries':
{
'positive': [
{y:341, url:'http://golf.com?q=positive'},
{y:487, url:'http://polo.com?q=positive'},
{y:180, url:'http://passat.com?q=positive'}
],
'neutral': [
{y:12, url:'http://golf.com?q=neutral'},
{y:3, url:'http://polo.com?q=neutral'},
{y:9, url:'http://passat.com?q=neutral'}
],
'negative': [
{y:222, url:'http://golf.com?q=negative'},
{y:115, url:'http://polo.com?q=negative'},
{y:321, url:'http://passat.com?q=negative'}
]
}
}
My approach is to loop over the categories and add positive, neutral and negative to seperate strings which I evaluate later on in the highcharts-setup.
var allPositiveData = '';
var allNeutralData = '';
var allNegativeData = '';
for(var i=0; i < categories.length; i++) {
var diaPositive = series['positive'][i]['y'];
var diaNeutral = series['neutral'][i]['y'];
var diaNegative = series['negative'][i]['y'];
urlPositive = series['positive'][i]['url'];
urlNeutral = series['neutral'][i]['url'];
urlNegative = series['negative'][i]['url'];
allPositiveData += "{'y': " + diaPositive + ", 'url': '" + urlPositive + "'}, ";
allNeutralData += "{'y': " + diaNeutral + ", 'url': '" + urlNeutral + "'}, ";
allNegativeData += "{'y': " + diaNegative + ", 'url': '" + urlNegative + "'}, ";
} // end of loop
allPositiveData = eval( "[" + allPositiveData.slice(0, -2) + "]" );
allNeutralData = eval( "[" + allNeutralData.slice(0, -2) + "]" );
allNegativeData = eval( "[" + allNegativeData.slice(0, -2) + "]" );
Highcharts-setup
newChart = new Highcharts.Chart({
chart : {
renderTo : 'container',
type: 'column'
},
[...] // skipping the rest of the setup
series: [
{
name: 'Positive',
data: allPositiveData
}, {
name: 'Neutral',
data: allNeutralData
}, {
name: 'Negative',
data: allNegativeData
}]
});
I figure there are a few ways to achieve what I want but I want to know a better (maybe object orientated) solution.
http://jsfiddle.net/x8455/
I think you are trying to do something what you already have done.
You want to get display three series from your JSON, for respective categories, then let's to that:
Your code:
var categories = testDia['chartCategories'];
var series = testDia['chartSeries'];
Great! Now use that variables:
newChart = new Highcharts.Chart({
chart : {
renderTo : portletContainer,
type: 'column'
},
...
xAxis: {
categories: categories,
labels: {
rotation: -45,
align: 'right',
}
},
...
series: [{
name: 'Positive',
data: series.positive // testDia.chartSeries.positive is the same
}, {
name: 'Neutral',
data: series.neutral
}, {
name: 'Negative',
data: series.negative
}]
});
And working demo: http://jsfiddle.net/x8455/1/
Here's how you should do it.
var allPositiveData = []; // You want an array, so start off with an array.
for(var i=0; i < categories.length; i++) {
var diaPositive = series['positive'][i]['y'];
urlPositive = series['positive'][i]['url'];
allPositiveData.push({'y':diaPositive, 'url':urlPositive}); // Add the element to the array.
}
That's all there is to it. Your Highcharts-setup piece of code can remain the same.
To make the sample a little shorter, I only edited the code for the positive data, the rest is the same, just a different name.

Get all selected ids of jqgrid in external javascript function

I am using multi-select grid functionality in my application and it is working as i expected. But the issue is i need to get all the selected records across the pagination in external javascript function. Below is my code,
function createCommodity(){
$.ajax({
url : 'commoditycategory.do?method=listCommodity' + '&random='
+ Math.random(),
type : "POST",
async : false,
success : function(data) {
$("#list2").jqGrid('GridUnload');
var newdata = jQuery.parseJSON(data);
var wWidth = $(window).width();
var dWidth = wWidth * 0.7;
var wHeight = $(window).height();
var dHeight = wHeight * 0.5, idsOfSelectedRows = [];
jQuery("#list2").jqGrid({
data : newdata,
datatype : "local",
colNames : [ "id", "Commodity Code",
"Commodity Description", "Commodity Category" ],
colModel : [
{
name : 'id',
index : 'id',
hidden : true,
editable : true
},
{
name : 'commodityCode',
index : 'commodityCode',
align : "center",
editable : true,
editrules : {
required : true
}
},
{
name : 'commodityDesc',
index : 'commodityDesc',
align : "center",
editable : true,
editrules : {
required : true
}
},
{
name : 'commodityCategoryId',
index : 'commodityCategoryId',
align : "center",
// hidden : true,
editable : true,
edittype : "select",
editoptions : {
dataUrl : 'commoditycategory.do?method=parentCategory'
+ '&random=' + Math.random()
},
editrules : {
edithidden : true,
required : true
// custom : true
}
} ],
pager : "#pager2",
rowNum : 10,
rowList : [ 10, 20, 50 ],
height : "230",
width : dWidth,
onSelectRow: function (id, isSelected) {
var p = this.p, item = p.data[p._index[id]], i = $.inArray(id, idsOfSelectedRows);
item.cb = isSelected;
if (!isSelected && i >= 0) {
idsOfSelectedRows.splice(i,1); // remove id from the list
} else if (i < 0) {
idsOfSelectedRows.push(id);
}
},
loadComplete: function () {
var p = this.p, data = p.data, item, $this = $(this), index = p._index, rowid, i, selCount;
for (i = 0, selCount = idsOfSelectedRows.length; i < selCount; i++) {
rowid = idsOfSelectedRows[i];
item = data[index[rowid]];
if ('cb' in item && item.cb) {
$this.jqGrid('setSelection', rowid, false);
}
}
},
multiselect : true,
cmTemplate : {
title : false
}
});
$grid = $("#list2"),
$("#cb_" + $grid[0].id).hide();
$("#jqgh_" + $grid[0].id + "_cb").addClass("ui-jqgrid-sortable");
cbColModel = $grid.jqGrid('getColProp', 'cb');
cbColModel.sortable = true;
cbColModel.sorttype = function (value, item) {
return typeof (item.cb) === "boolean" && item.cb ? 1 : 0;
};
}
});
}
Till now its working great. Its holding correct rows which are selected across pagination.
And My external JS function where i need to get the selected rowids include pagination is,
function updateCommodity() {
var grid = jQuery("#list2");
var ids = grid.jqGrid('getGridParam', 'selarrrow'); // This only returns selected records in current page.
if (ids.length > 0) {
var html = "<table id='commodityTable' class='main-table' width='100%' border='0' style='border:none;border-collapse:collapse;float: none;'><thead><td class='header'>Commodity Code</td><td class='header'>Commodity</td><td class='header'>Action</td></thead><tbody>";
for ( var i = 0, il = ids.length; i < il; i++) {
var commodityCode = grid.jqGrid('getCell', ids[i],
'commodityCode');
var commodityDesc = grid.jqGrid('getCell', ids[i],
'commodityDesc');
html = html
+ "<tr class='even' id='row" + i + "'><td><input type='text' name='commodityCode' id='geographicState"+i+"' class='main-text-box' readonly='readonly' value='" + commodityCode + "'></td>";
html = html
+ "<td><input type='text' name='commodityDesc' id='commodityDesc"+i+"' class='main-text-box' readonly='readonly' value='" + commodityDesc + "'></td>";
html = html
+ "<td><a style='cursor: pointer;' onclick='deleteRow(\"commodityTable\",\"row"
+ i + "\");' >Delete</a></td></tr>";
}
html = html + "</tbody></table>";
$("#commodityArea").html(html);
}
}
Update I have fiddled the issue for providing more clarity about the issue.
First of all I want remind that you use the code which I posted in the answer.
I see that the solution of your problem is very easy. The list of options of jqGrid can be easy extended. If you just include new property in the list of options
...
data : newdata,
datatype : "local",
idsOfSelectedRows: [],
...
you will don't need more define the variable idsOfSelectedRows (see the line var dHeight = wHeight * 0.5, idsOfSelectedRows = []; of you code). To access new option you can use
var ids = grid.jqGrid('getGridParam', 'idsOfSelectedRows');
instead of var ids = grid.jqGrid('getGridParam', 'selarrrow');. To make the code of onSelectRow and loadComplete callbacks working with idsOfSelectedRows as jqGrid option you should just modify the first line of the callbacks from
var p = this.p, ...
to
var p = this.p, idsOfSelectedRows = p.idsOfSelectedRows, ...
It's all.
UPDATED: See http://jsfiddle.net/OlegKi/s2JQB/4/ as the fixed demo.

plotting realtime data and turning on and off data series using flot api

I am using flot charts. I want to plot chart which is updated per second and also want to add the feature of turning off and on the data series.
I am able to make it work but has problems which I did not expect, like color of one series change when other series is turned off; other is when I update the array of data series the charts seems to move but it removes element from the right,at the same time the new value is plotted on the right hand side ...
var d1 = [] ;
var d2 = [] ;
var d3 = [] ;
$(function(){
{%for reading in readings%}
var time_stamp = parseFloat({{reading['timestamp']}} + 19800.00) * 1000
var A = parseFloat({{reading['values']['A']}}) ;
var V = parseFloat({{reading['values']['VLN']}}) - 50 ;
var W = parseFloat({{reading['values']['W']}}) / 1000 ;
d1.push([time_stamp,A]);
d2.push([time_stamp,V]);
d3.push([time_stamp,W]);
{%endfor%}
var datasets = {
"current":{
label : "A",
data : d1
},
"voltage":{
label : "V",
data : d2
},
"power":{
label : "W",
data : d3
},
}
var i = 0;
$.each(datasets, function(key, val) {
val.color = i;
++i;
});
// insert checkboxes
var choiceContainer = $("#choices");
$.each(datasets, function(key, val) {
choiceContainer.append("<br/><input type='checkbox' name='" + key +
"' checked='checked' id='id" + key + "'></input>" +
"<label for='id" + key + "'>"
+ val.label + "</label>");
});
choiceContainer.find("input").click(plotAccordingToChoices);
function plotAccordingToChoices() {
var data = [];
choiceContainer.find("input:checked").each(function () {
var key = $(this).attr("name");
if (key && datasets[key]) {
data.push(datasets[key]);
}
});
if (data.length > 0) {
$.plot("#placeholder", data, {
series: {
shadowSize: 0,
lines: {
show: true
},
},
yaxis: {
min: 0
},
xaxis: {
tickDecimals: 0,
mode:"time"
}
});
}
setTimeout(getNextDataset,1000);
}
plotAccordingToChoices();
});
function getNextDataset()
{
$.ajax({url : '/newdata' , success:function(result){
reading =JSON.parse(result);
var time_stamp = (parseFloat(reading.timestamp) + 19800.00) * 1000
var A = parseFloat(reading.values.A) ;
var W = parseFloat(reading.values.W) / 1000 ;
var V = parseFloat(reading.values.VLN) - 50 ;
d1.shift();d2.shift();d3.shift();
d1.push([time_stamp,A]);
d2.push([time_stamp,V]);
d3.push([time_stamp,W]);
var datasets = {
"current":{
label : "A",
data : d1
},
"voltage":{
label : "V",
data : d2
},
"power":{
label : "W",
data : d3
},
}
var data = [] ;
var choiceContainer = $("#choices");
choiceContainer.find("input:checked").each(function () {
var key = $(this).attr("name");
if (key && datasets[key]) {
data.push(datasets[key]);
}
});
if (data.length > 0) {
$.plot("#placeholder", data, {
series: {
shadowSize: 0,
lines: {
show: true
},
points:{
show:false
},
},
yaxis: {
min: 0
},
xaxis: {
tickDecimals: 0,
mode:"time"
}
});
}
}
});
setTimeout(getNextDataset,1000) ;
}
`
I am making use of code available in flot charts examples.Where am I going wrong ??
Thank you ?
Problem 1 : Color updating every time a checkbox was checked or unchecked
Reason: Every time the checkbox click event was triggered,some how the color used to get updated
Solution : Removed setTimeout(getNextDataset,1000); call from the function plotAccordingToChoices()
Problem 2: The data elements are removed from the right instead of left.
Reason : (Very dumb) Data was coming in descending order and I was using pushing data in that order only.So latest point was at location 0 of the array and oldest point was at location n-1.And I was removing (n-1)th point.
Solution : Replaced push in the beginning with unshift().Did the magic :P

Categories