I have j-Query data-table with many records and I have builtin search-box. What I am trying is to sum all values in all the tds which have class="amount". It's happening succesfully. Now, the problem is search box. I want to sum the values of tds with class name amount which are only visible. I tried many ways but nothing worked Following is my code:
var salaryTable = $('#tblSalary').DataTable();
salaryTable.on('search', function () {
var sum = 0;
$(".amount").each(function() {
var value = $(this).text();
if(!isNaN(value) && value.length != 0) {
sum += parseFloat(value);
}
});
alert(sum);
});
This logic is not working as expected. How can I solve this or What am I doing wrong? Is there any better approach?
Update: The problem is when I search something it gives me total of visible and invisible records. When I clear the search box with backspace, it gives me total of all records where were visible before.
If you only want visible elements with class amount you could use the jQuery :visible selector
$(".amount:visible").each(...)
jQuery docs https://api.jquery.com/visible-selector/
Related
This is similar to dc.js - how to create a row chart from multiple columns but I want to take it a step further and enable filtering when the rows are clicked.
To answer the question "What is it supposed to filter?" - Only show records with value > 0. For example when Row 'a' is clicked it will only show records with value for a > 0. Hence, the Type pie chart will change to foo:1, bar:2
I guess I have to overwrite onClick method? But I am not sure how.
chart.onClick = function(d) {}
jsfiddle from the answer to the above question - http://jsfiddle.net/gordonwoodhull/37uET/6/
Any suggestions?
Thanks!
Okay, here's a solution where if a record has values > 0 for any of the selected rows, that record is included. As #Ethan said, it's a matter of defining a filter handler:
sidewaysRow.filterHandler(function(dim, filters) {
if(filters && filters.length)
dim.filterFunction(function(r) {
return filters.some(function(c) {
return r[c] > 0;
});
})
else dim.filterAll();
return filters;
});
Also, since the filterFunction only has access to the key, we pass the entire record through as the key. This doesn't make a whole lot of sense in the "real world" but since we're already using crossfilter sideways, it is probably fine:
var dim = ndx.dimension(function(r) { return r; });
New version of the fiddle: https://jsfiddle.net/gordonwoodhull/b7cak6xj/
BTW it sounds like you want to only select one row at a time. Here's how to do that:
sidewaysRow.addFilterHandler(function(filters, filter) {
filters.length = 0;
filters[0] = filter;
return filters;
})
(This will be simpler in dc 2.1 on the develop branch, where the charts use the result of the filter handlers instead of requiring you to modify the filters in place; the body becomes just return [filter];)
I have a slickGrid which is using dataView to render student grades. I would like to default sort the grid prior to it being rendered by column with id = 0 and field = 'Student'. How can I trigger sort event on this column before the grid renders?
The reason why I want to do this is because I have a really strange bug that can be seen in this video:
http://screencast.com/t/Oz0vlcsQPp
The sorter works fine on the 1st asc/des sort but then it goes all out of whack. Noting is sorted the way it should be. However if I 1st sort by student name then the sorter on any other column works just fine without any issues no matter how many times I sort. If I refresh the page the problem happens again.
Since I cannot even begin to understand why is this happening my only hope is to initially fire a sort on the student column and bypass the problem all together.
NOTE: I am using the naturalSort.js from here: https://github.com/overset/javascript-natural-sort/blob/master/naturalSort.js. I don't think the sort is the issue since it works fine when I initially sort by student name... This one is breaking my brain...
EDIT: As you can see in the video my grid cell data looks something like "A (78.65%)". My data structure looks like this:
"Column_3":{"displayValue":"A (100%)","sortValue":100.0},
"Column_4":{"displayValue":"B (87.53%)","sortValue":87.53},
"Column_5":{"displayValue":"?","sortValue":-1.0}
I am sending over an object for sorting reasons in order to use percentage as a sorting criteria. In order to make this work I have defined dataItemColumnValueExtractor in grid options as such:
self.options["dataItemColumnValueExtractor"] = getItemColumnValue;
function getItemColumnValue(item, column) {
var values = item[column.field];
return values.displayValue !== undefined ? values.displayValue : values;
}
This allows me to use the sortValue data to sort the grid. Here is my sort event:
grid.onSort.subscribe(function(e, args){
var comparer = function(a, b) {
var result;
if (a[args.sortCol.field].sortValue !== undefined && a[args.sortCol.field].sortValue !== null && b[args.sortCol.field].sortValue !== undefined && b[args.sortCol.field].sortValue !== null) {
result = naturalSort(a[args.sortCol.field].sortValue,b[args.sortCol.field].sortValue);
}
else {
result = naturalSort(a[args.sortCol.field],b[args.sortCol.field]);
}
return result;
};
dataView.sort(comparer, args.sortAsc);
});
Bottom line is everything works fine except the above mentioned issue with sorting... Any help would be appreciated...
First of all...your issue for first time sorting is something else which can be fixed...
But if you want to sort a col on grid load you can trigger the click event....
$(function () {
for (var i = 0; i < 50000; i++) {
var d = (data[i] = {});
d["num"] = i;
.
.
d["effortDriven"] = (i % 5 == 0);
}
dataView = new Slick.Data.DataView();
grid = new Slick.Grid("#myGrid", dataView, columns, options);
$('.slick-header-columns').children().eq(2).trigger('click'); // eq(2) for the 3rd col
}
I'm using a stacked bar chart in v2013.2.726 of kendo-ui. I would like to base a grand total calculation off of the enabled items in the chart's legend. So far I have not found a consistent way to tell which legend items are enabled.
I tried the following but it does not work because kendoChart._sourceSeries[i].visible does not consistently match the visual state after multiple clicks on legend items.
function onLegendItemClick(clickEventArgs) {
var total = 0;
for (var i = 0; i < self.kendoChart._sourceSeries.length; ++i) {
if ((clickEventArgs.text === self.kendoChart._sourceSeries[i].name &&
!self.kendoChart._sourceSeries[i].visible) ||
(clickEventArgs.text !== self.kendoChart._sourceSeries[i].name &&
self.kendoChart._sourceSeries[i].visible)) {
total += chartModel.Series[i].Total;
}
}
...
};
So is it even possible to determine which legend items are enabled?
So I started looking into implementing something to track the item state outside of kendo. It was only then I noticed the property kendoChart.options.series[i].visible which does indicate the state.
My apologies for answering my own question but there was not much traffic to it or the question I posted on the kendo-ui forum. So I figured I should share what I found.
I assume you can to loop through the visible (active) elements that are being displayed in the Kendo chart and then display that Total.
Instead of searching which items are active you can directly get them through the dataSource.view() method.
I have 6 textboxes at the top of the screen that update an entire column(one textbox per column) based on any changes. I was selecting the columns based on their class (.l#). Here is the code (issues to follow):
function UpdateField() {
var ctrl = this;
var id = parseInt(ctrl.id.replace("item", ""), 10) - 1;
var bound = [".l1", ".l7", ".l8", ".l9"];
var fields = $(bound[id]);
for (var i = 0; i < fields.length; i++)
{
fields[i].innerHTML = $(ctrl).val();
}
};
which is bound to the keyup event for the text areas. Issues are:
1) initially fields.length was -1 as I didn't want to put data in the "add new
row" section at the bottom. However, when running it, I noticed the
final "real" record wasn't being populated. Also, when stepping through, I
noticed that the "new row" field was before the "last row" field.
2) when doing it this way, it is purely superficial: if I double click the field,
the real data hasn't been changed.
so in the grand scheme of things, I know that I was doing it wrong. I'm assuming it involves updating the data and then forcing a render, but I'm not certain.
Figured out how to do it. Modified the original code this way:
function UpdateField() {
var ctrl = this;
var id = parseInt(ctrl.id.replace("item", ""), 10) - 1;
var bound = ['title1', 'title2', 'title3', 'title4'];
var field = bound[id];
for (var i = 0; i < dataView.getLength(); i++)
{
var item = dataView.getItem(i);
item[field] = $(ctrl).val();
dataView.updateItem(i, item);
}
grid.invalidate();
};
I have 6 textboxes (item1-item6) that "bind" to fields in the sense that if I change data in a textbox, it updates all of the rows and any new rows added also have this data.
Parts where the two issues can be explained this way:
1) to work around that, though still it would be a presentational fix and not a real updating of the underlying data, one could force it to ignore if it had the active class attached. Extra work, and not in the "real" direction one is going for (masking the field).
2) It was pretty obvious with the original implementation (though it was all I could figure out via Chrome Dev Tools that I could modify at the time) that it was merely updating a div's content and not actually interacting with the data underneath. Would look nice, and perhaps one could just pull data from the item1-item6 boxes in place of the column if it is submitted, but if someone attempts to modify the cell, they'll be looking at the real data again.
Ok, let me explain my scenario more clearly:
When a cell is edited, it becomes 'dirty' and I style it a certain way by adding a CSS class to the cell via javascript.
Then, if the user Sorts the grid, the styling is lost (I believe because all the rows are recreated) and I need a way to restore the styling to the appropriate cell/row after a Sort.
What I attempted to do is add an entry into data[] called 'status' and onCellChange I loop through data[] and match the args.item.Id to appropriate entry in data[].
grid.onCellChange.subscribe(function (e, args) {
var done = false;
for (var i = 0; i < data.length && !done; i++) {
if (data[i].id == args.item.id) {
data[i].status = "dirty";
done = true;
}
}
}
However, onSort I'm not sure how to match the sorted rows to the data array. (Since I have no args.item) I've attempted to do selector statements:
$(".slick-row")
to restyle the correct cells, but I have no way to associate the rows with their entry in data[].
1) There is no need to search for the item in your onCellChange handler - it is available at "args.item".
2) Sorting the "data" array will not wipe out your change to the item in #1.
3) You mention dynamically styling cells. I see no code for that. If your custom formatter is the piece of code that looks at "item.status" and renders it differently if it is dirty, then you don't have to do anything extra. Sorting the data and telling the grid to re-render will preserve the "dirty" cell styles.