SlickGrid: Get the total no of rows after Grouping - javascript

I am grouping the slickgrid table, and I want to know the no.of rows after grouping.
I found this solution
grid.getData().getPagingInfo().totalRows
from this question.
But it is not working for the table after grouping.
It returns the total no.of rows of the data not the updated no.of rows after grouping.
Please help me to solve this

Not sure if I understand your question right, but to me it seems that you are confusing Slick objects here. The grid.getData() will return the complete datasource of your grid.
If you take a look at the official SlickGrid example-grouping demo, you will see a grid with grouped set of datas. You can try yourself by opening your favorite browsers Javascript debugger:
dataView.getGroups()
It will return you the corresponding Array of objects from the dataview that contains all groups informations like:
Array [ Object, Object, ... , another 15... ]
You can reach these objects thru specifying the given element key of the returned array:
dataView.getGroups()[0]
Return value of command:
Object {__group: true, level: 0, count: 1, value: 0, title:
"Duration: 0 1, groups: null, groupingKey: "0"}
Now we can see that it has a count property which contains the exact number of rows belong to that group.
So finally by issuing:
dataView.getGroups()[0].count
Will return you:
1
Or by issuing:
dataView.getGroups()[1].count
Will return you:
3
Where both returned count numbers equal with the record numbers you can see in the grid.

Related

Cannot get values of a column with getRange and getValues

Here is the code I have so far:
var items = data.getRange(1,14,1,lc).getValues()[0];
var names = cdata.getRange(52, 1, 28,1).getValues()[0];
When I log 'items' I get the desired information populated in a single array.
When I try to get the 'names' in a column using a similar method I can only get the first cell in a single array or all of the desired cells in an array of arrays.
example of items
[item1,item2,item3,...]
example of names
[name1] or [[name1],[name2],[name3],[...]]
Why am I not able to use the same method to accurately retrieve the names in a column as I did in the row? How do I fix this and get the desired result? How do I get names to return the data in the cells as I did with items?
I see you have 1 column for names combined with []. That will return a [] result from a a structure like [ [][][] ] (not [ [] ]). If your items have multiple rows, you'll get the entire first row [,,,], as you suggest in items.
var items = data.getRange(1,14,1,lc).getValues()[0];
var names = cdata.getRange(52, 1, 28,1).getValues()[0];
That's more a diagnosis than an answer. Basically, you're getting what you should get from that, but I think you want it transposed. Various ways to do that.
But will this work?
// flatten(flatten()) works for 2-level nesting, and so on
function flatten(arrayOfArrays){
return [].concat.apply([], arrayOfArrays);
}
reference: https://gist.github.com/MauricioMoraes/225afcc9dd72acf1511f
You will have to use this instead:
var names = cdata.getRange(52, 1, 28,1).getValues().flat();

Reverse data from Fauna DB

I have been looking at the docs indexes for FQL and Fauna DB. Is there a way to reverse the order of the data returned from the query?
Here is the code I have:
q.Map(
q.Paginate(q.Match(q.Index("all_pages")), {
//! Find way to change order
size: 3
}),
ref => q.Get(ref)
)
The docs mention the reverse flag.
Does anyone know how to use it?
Imagine you have a collection that contains documents with a price field, let's call it ... ermm ... priceables!
Let's add two documents to the collection with price 1 and price 2.
[{
"price": 1
},
{
"price": 2
}]
Image in UI console of the documents
Create a regular index
Create a regular range index on that price value with the following snippet:
CreateIndex({
name: "regular-value-index",
unique: false,
serialized: true,
source: Collection("priceables"),
terms: [],
values: [
{
field: ["data", "price"]
}
]
})
Create a reverse index
There can be multiple values (e.g. a composite index) and the reverse field can be set per value.
To create a reverse index, set reverse to true for that specific value.
CreateIndex({
name: "reverse-value-index",
unique: false,
serialized: true,
source: Collection("priceables"),
terms: [],
values: [
{
field: ["data", "price"],
reverse: true
}
]
})
If you go to the UI console and open the index you will notice the values are sorted from highest to low.
UI console, reverse index
I assume that what confused you is that you can't set the reverse boolean in the UI yet. But you can just go to Shell and paste in the FQL code to create the index: Image of the shell
I just reversed an Index successfully. The docs are helpful, but they don't give an example where the Map function is implemented. The secret is to wrap the Map function as well, with q.Reverse:
q.Reverse(
q.Map(
q.Paginate(q.Match(q.Index("all_pages")), {
//! Find way to change order
size: 3
}),
ref => q.Get(ref)
)
)
This should work for you!
The best way to reverse the order of data is to use an index, per Brecht's answer. Fauna stores index entries in sorted order, so when your index uses reverse: true matching entries from the index are already sorted in reverse order.
WΔ_'s answer is technically correct, but probably not what you want. Using Reverse around a Paginate reverses the items in the page, but not the overall set. Suppose your set was the letters of the alphabet, and your page size is 3. Without Reverse, you'd expect to see pages with ABC, DEF, etc. If you're trying to change the order of the set, you'd expect to see ZYX, WVU, etc. WΔ_'s answer results in CBA, FED, etc.
Reverse can operate on a set. So you can Reverse(Match(Index("all_pages"))), and Paginate/Map that result. Note that for large sets, your query might fail since Reverse has to operate on the entire set.

MongoDB updating nested array with sort and slice, doesn't sort desc

I'm trying to push objects to an embedded array and sort by desc while slicing at 5.
This works if I change created to 1, but it's 'ascending'. What happens now, is new objects, don't actually get inserted into the array, if it's has 5.
Any idea how to do this? Thank you!
db.user.update({_id : user_id},
{ "$push" : { items : { "$each" : [{
action : 'one',
status : 'two',
value : 'three',
created: new Date()
}
],
"$sort" : {created: -1},
"$slice" : -5
}
}
}
, function(err, doc) {
});
What is happening is that you have asked MongoDB to sort the items in descending order and keep only the last 5; this means that only the 5 smallest items will be kept. But since you are inserting the items in ascending order (because Date() keeps increasing), once you have inserted 5 items you already have the 5 smallest items, so no subsequent ones will be inserted.
As you have noted if you change the sort order to ascending then you will be keeping the 5 largest items; since every new item has a larger Date() than all the previous ones, every new item will initially be among the largest 5 items so will appear in the list.
If you need the 5 largest items sorted in descending order you could use the ascending sort order when you $push the item in order to use $slice to keep the largest 5, and then when you query the data you can reverse the order of the results in the client.
Everything in your code works as expected. And because of this you actually do not see any results.
What your code is doing:
Find the document with _id = user_id
In its key items insert a bunch of objects (it happens that bunch = 1)
then sort that key items in a decreasing order by the field created
and leave only 5 smallest elements.
The problem appears because of the Date() field. Date is increasing all the time. So every new element will not end up in this 5 smallest elements. When you change you created : 1, you sort by increasing order and your new date surely end up in the 5 elements.
Regarding this:
Any idea how to do this? Thank you!
If you would better describe what you want I hope I will be able to tell you what you can change, because right now your script is doing exactly the right thing. As you mention, you can put created : 1

storing table cell content into js array

I need to store table cell content into array using tr and td indexes like this:
myArray[tr_idx][td_idx]='value';
It is not required to store data of all of cells in array but only several with a special content, but if i use indexes as a keys of the array i'll have many empty array elements.
e.g.
myArray[2][3]='data1';
myArray[4][3]='data2';
alert (myArray.toSource()) -> [, , [, , , "data1"], , [, , , "data2"]]
maybe there is another suitable way of storing such type of data?
Why not just store them as individual 2-item arrays [row,col]? Since the table cells are already accessible via tableElement.rows[].cells[], you can use the 2 indices to access them from the table.
var storedCells = [];
// Store row 2, column 3
storedCells.push([2,3]);
Access with:
// Table row:
storedCells[0][0]
// Table column
storedCells[0][1]
//As in :
tableElement.rows[storedCells[0][0]].cells[storedCells[0][1]].innerHTML = "New cell value!"
Or even cleaner, if you prefer to use objects rather than arrays:
storedCells.push({row: 2, column: 3});
storedCells.push({row: 4, column: 6});
Accessed with:
tableElement.rows[storedCells[0].row].cells[storedCells[0].column].innerHTML = "New cell value!";
Finally, if you don't actually need the row/column indexes, but rather the DOM nodes themselves, just push those onto your array.
var storedCells = [];
// Save references to some individual <td> nodes
storedCells.push(tableElement.rows[1].cells[2]);
storedCells.push(tableElement.rows[4].cells[6]);
They are then trivially modified:
// Set the value of the second element:
storedCells[1].innerHTML = "New content!";
Update after comment:
If you need to be able to attach the cell coordinates to a new value from the backend, a good solution would be to expand the object {} example above to include a value attribute. The server can pass back the new value in JSON.
storedCells.push({row: 2, column: 3, value: ""});
storedCells.push({row: 4, column: 6, value: ""});
Your backend should send a JSON response back to the script containing the same type of array of objects, where value: has been populated with the new cell value. You can then pass it back into the table with:
// Pass the value attribute received from JSON into the cell's contents
tableElement.rows[storedCells[0].row].cells[storedCells[0].column].innerHTML = storedCells[0].value;
Not sure if this is the right answer but you could try to check if cells are empty before pushing them into the array. In the loop place a an if statement that will check the value of the cell and compare it to the value you require. This way you should end up with just an array of value and no empties. But you may need to record the index as well then.

Highcharts breaks up my data array in a strange way

I'm using Highcharts (link to a specific demo -- click View Options to compare below code) to render some data for personal-use.
[Note: this is almost definitely a me-related error, so I don't mean to insinuate that Highcharts is at fault -- it's really a wonderful api!]
When setting the series.data field of the chart object, I encounter strange array sectioning.
For instance, this works fine:
series: [{
name: 'seriesName',
data: [22, 24, 15]
}]
And three data points are plotted with values 22, 24 and 15.
However,
series: [{
name: 'sillySeries',
data: chartData[0]
}]
renders 3 points with the values 2, 4 and 5 and the titles of the points are 2, 2 and 1 respectively... that is, it's splitting the array entries into a title and then a value for two-digit numbers.
console.log shows me that chartData looks like
22,24,15,2010-9,2010-10,2010-11
(3 values for 3 months)
Although the actual arrays are more like [22,24,15][2010-9,2010-10,2010-11]
My 2d-array chartData[][] has [column][row] indices for the data, and I figured that asking for chartData[0] would return an array.
Perhaps my question should be: How do I return a 1d array from a 2d array representation for setting properties/values in javascript objects? It seems like I'm probably overlooking something very obvious.
edit:
data: [24]
plots one point at 24, awesome.
data: '24'
splits up the data as title and then value, effectively plotting a point at 4 and not 24.
So the representation becomes a string when I try to pass an array to the data field. Any way I can do like string.toArray ?
edit 2:
chartData[col][row] is declared as an empty array
var chartData = [];
and subsequently filled up with values by iterating over an HTML table's rows and columns, where the innermost loop contents look like
chartData[cellIndex][rowIndex] = $(currentCell).text();
While chartData is probably an array, it sounds like chartData[0] is a string. When you use an array index on a string you get the character at that position, which is exactly what you are experiencing...
renders 3 points with the values 2, 4 and 5 and the titles of the points are 2, 2 and 1 respectively... that is, it's splitting the array entries into a title and then a value for two-digit numbers.
There are many ways to define arrays within arrays in javascript; here is one:
var chartData = [
[22,24,15]
,['2010-9','2010-10','2010-11']
];
parseInt() saved the day.
something like
for (i=0; i<chartData[0].length; ++i) {
columnOne.push(parseInt(chartData[0][i]);
}
gave me an array that I could then use to display the data with the data field in the object notation
data: columnOne
or more literally
chart1.series[0].data = columnOne;
Thank you James for pointing out
While chartData is probably an array, it sounds like chartData[0] is a string.
which lead to my discovery that the data in my array was actually all strings, which I kept this way because some fields are strings, some are dates (YYYY-MM-DD) and some are just ints.
Many thanks to you both =)
Well, this is not a real answer, but might help you.
Highcharts enables you to preprocess certain options. In your case, you could do something like :
options.series[0].data = new Array(1, 0, 4);
doc reference : http://www.highcharts.com/documentation/how-to-use#options
If this fails, comment above.

Categories

Resources