How can I export AgGrid data in case of infinite row model (infinite scrolling) in react - export-to-csv

How can I export AgGrid data in case of infinite row model (infinite scrolling) in react.
For the normal row models it is being done in this way:
this.gridOptions.api.exportDataAsCsv(params);
What about infinite row model case?

Here is the solution that I've implemented.
Grid footers, multiple headers is not considered here.
This code is for simple grid with headers and rows under it.
In case of infinite scrolling and dynamic columns (in some cases columns can be changed).
var LINE_SEPARATOR = '\r\n';
var COLUMN_SEPARATOR = ',';
var fileName = 'export.csv';
let csvString = '';
let columnsToExport = this.gridOptions.api.columnController.getAllDisplayedColumns();
// adding column headers.
columnsToExport.map((column) => {
csvString+= column.colDef.headerName;
csvString+= COLUMN_SEPARATOR;
});
csvString+= LINE_SEPARATOR;
// adding content of data currently loaded in the grid.
this.gridOptions.api.forEachNode( function(node) {
node.columnController.allDisplayedColumns.map((column) => {
let cellContent = node.valueService.getValue(column, node);
csvString+= (cellContent != null) ? cellContent : "";
csvString+= COLUMN_SEPARATOR;
});
csvString+= LINE_SEPARATOR;
});
// for Excel, we need \ufeff at the start
var blobObj = new Blob(["\ufeff", csvString], {
type: "text/csv;charset=utf-8;"
});
// Internet Explorer
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blobObj, fileName);
}
else {
// Chrome
var downloadLink = document.createElement("a");
downloadLink.href = window.URL.createObjectURL(blobObj);
downloadLink.download = fileName;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}

Related

How to get tags around selected text in a contenteditable?

I'm trying to do an handler for applying certain formatting style (bold/cursive) at the click of respective button.
In particular, I want to handle selection of text: I want to toggle tags in a selection (tags are combinable).
I tried this way, but I think there should be better ideas. I found the nearest container to selected text, than I found all of its ancestors inside textarea.
var selection = document.getSelection();
var selectedText = selection.toString();
var range = selection.getRangeAt(0).cloneRange();
var firstTag = $("#textarea-ce *:contains("+selectedText+")");
var currNode = firstTag;
var newNode = $(document.createTextNode(selectedText))[0];
var currTagName;
var currTag;
var lastTag = false;
var found = false;
while (!lastTag) {
currTagName = $(currNode).prop('tagName').toLowerCase();
currTag = $("<"+currTagName+"><"+currTagName+"/>")[0];
if (currTagName != selectedTagName){
newNode = $(currTag).html(newNode);
}
else {
found = true;
}
if ($(currNode).parent().attr('id') == 'textarea-ce') {
lastTag = true;
}
else {
currNode = $(currNode).parent();
}
}
currNode = $(textarea).find(currNode)[0];
var newNodeContent = $(newNode).html();
if (!found) {
newNodeContent = "<"+selectedTagName+">"+newNodeContent+"<"+selectedTagName+"/>";
newNode = $(selectedTag).html($(newNode));
}
if (currTagName.startsWith("h")){
$(currNode).html(newNodeContent);
range.insertNode(currNode);
}
else {
$(currNode).replaceWith(newNode);
}
I used header (h1, h2,...) displayed as inline for sizing text.
In order to get surrounding tags I tried also with documentFragment (range.extractContents) but after a selection, sometimes it doesn't include tags, but only the text node.
The hardest challenge is to handle the case in which the user selects part of a formatted text and removes one of those tags.
Any suggestion is appreciated.

getting error reading the excel file in flutter web

here is my code it's printing the encrypted data
ht.InputElement File = ht.FileUploadInputElement();
File.click();
File.onChange.listen((event) {
final file = File.files.first;
final reader = ht.FileReader();
var a = file.name;
if(a.contains('.xlsx')) {
reader.onLoadEnd.listen((event) {
var decoder = SpreadsheetDecoder.decodeBytes(reader.result);
var table = decoder.tables['Sheet 1'];
var values = table.rows[0];
print(values);
});
}
output
js_primitives.dart:47 [� [!��Ov�!���%������L�vo���W�F���"�8\��(2z�
I want to print the data at row 0
can anyone help me in this
Okh so I solved it finally just need to add
reader.readAsArrayBuffer(file);
before reader.onLoadEnd

NativeScript - how can I filter an observable array with SearchBar?

Hi I'm trying to filter an observable array of data fetched via a HTTP request on keypress of the SearchBar.
I managed to get the SearchBar property change to work but I can't seem to figure out what I'm doing wrong in the filtering logic.
Ideally I want to update the list as I type in the search term in the SearchBar. I've searched the API on the Telerik site, there wasn't really any examples I could find.
XML
<Page loaded="pageLoaded">
<ActivityIndicator busy="{{ isLoading }}" />
<ActionBar title="People">
</ActionBar>
<GridLayout>
<StackLayout>
<SearchBar id="searchBar" hint="Search for someone"></SearchBar>
<ListView items="{{ peopleList }}" itemTap="showDetail">
<ListView.itemTemplate>
<StackLayout>
<Label text="{{ fullName }}" horiztonalAlignment="left" verticalAlignment="center"></Label>
<Label text="{{ company }}" class="info"></Label>
</StackLayout>
</ListView.itemTemplate>
</ListView>
</StackLayout>
</GridLayout>
</Page>
JS
var frames = require("ui/frame");
var Observable = require("data/observable").Observable;
var PeopleListViewModel = require("../../shared/people-viewModel");
var activityIndicatorModule = require("ui/activity-indicator");
var page;
var userkey;
var peopleList = new PeopleListViewModel([]);
var pageData = new Observable({ peopleList: peopleList });
exports.pageLoaded = function(args) {
page = args.object;
page.bindingContext = pageData;
userkey = userkey || page.navigationContext.userkey;
peopleList.load(userkey); // fetch data from the backend
var searchBar = page.getViewById("searchBar");
searchBar.on("propertyChange", function (args) {
var searchText = args.object.text;
if (searchText === "") {
// NOT SURE WHAT TO DO HERE.
} else {
peopleList.filter(function (element, index, array) {
// DOESN"T WORK PROPERLY
console.log("element: ", JSON.stringify(element));
return element.fullName == searchText;
});
console.log("Text types: ", searchText);
}
});
};
exports.showDetail = function(args) {
var person = peopleList.getItem(args.index);
var navigateEntry = {
moduleName: "views/people/people-detail",
context: { person: person },
animated: false
};
frames.topmost().navigate(navigateEntry);
};
PeopleListViewModel.js
var config = require("./config");
var fetchModule = require("fetch");
var ObservableArray = require("data/observable-array").ObservableArray;
function PeopleListViewModel(people) {
var viewModel = new ObservableArray(people);
viewModel.load = function (userKey) {
return fetchModule.fetch(config.baseUrl + "/api/people/all/" + userKey)
.then(function (response) {
return response.json();
})
.then(function (data) {
data.forEach(function (person) {
viewModel.push(person);
});
}, function (error) {
console.log("Error: ", error);
});
};
viewModel.empty = function () {
while (viewModel.length) {
viewModel.pop();
}
};
return viewModel;
}
function handleErrors(response) {
if (!response.ok) {
console.log("Error occurred");
}
}
module.exports = PeopleListViewModel;
Updated people-list
var frames = require("ui/frame");
var Observable = require("data/observable").Observable;
var ObservableArray = require("data/observable-array").ObservableArray;
var PeopleListViewModel = require("../../shared/people-viewModel");
var activityIndicatorModule = require("ui/activity-indicator");
var page;
var userkey;
var peopleList = new PeopleListViewModel([]);
var pageData = new Observable({ peopleList: peopleList });
var resultList = new ObservableArray([]);
exports.pageLoaded = function(args) {
page = args.object;
page.bindingContext = pageData;
userkey = userkey || page.navigationContext.userkey;
peopleList.load(userkey);
var searchBar = page.getViewById("searchBar");
searchBar.on("propertyChange", function (args) {
var searchText = args.object.text;
if (searchText === "") {
} else {
while (resultList.length > 0) {
resultList.pop();
}
peopleList.forEach(function (element) {
if (element.fullName === searchText) {
resultList.push(element);
}
});
}
});
};
I had the same issue. If you want to filter your data after every character has changed in search-bar you can try my solution.
Definitions
My playerList is your peopleList. This is the data from view-model.
resultList is an array where the data will be pushed.
var observableArrayModule = require("data/observable-array").ObservableArray;
var playerList = new PlayerListViewModel([]);
var resultList = new observableArrayModule([]);
var pageData = new observableModule.Observable({
resultList: resultList,
player: ""
});
Inside expors.loaded()
page = args.object;
searchBar = page.getViewById("search-bar");
page.bindingContext = pageData;
Load Initial Data - inside expors.loaded()
We are loading initial data when user navigates to the screen for the first time. We are also pushing the same data to resultList since we are using {{resultList}} in xml. You can add loadingIndicator while the list is populated.
playerList
.load()
.then(function() {
setTimeout(function() {
playerList.forEach(function (element) {
pageData.resultList.push(element);
});
}, 1000);
})
.catch(function(error) {
dialogsModule.alert({
message: "An error occurred while loading players.",
okButtonText: "OK"
});
});
Clear autofocus - inside expors.loaded()
This is to prevent keyboard from opening on initial screen navigation.
if (searchBar.ios) {
searchBar.ios.endEditing(true);
} else if (searchBar.android) {
searchBar.android.clearFocus();
}
Search data when character has changed - inside expors.loaded()
I am calling filter functionality. Lodash _.debounce function is used to delay looping through resultList array. Without it, the app would loop every time letter is typed. Now we are waiting for user to stop typing to start looping.
searchBar.on('propertyChange', _.debounce(searchList, 500));
searchList Function
This is the actual loop. You can change element.name for your needs.
function searchList(args) {
var searchText = args.object.text;
while(resultList.length > 0) {
resultList.pop();
}
playerList.forEach(function (element) {
if (element.name.toLowerCase().indexOf(searchText) >= 0) {
resultList.push(element);
}
});
}
Hide keyboard if search-bar is cleared - inside exports.loaded()
And finally we want to hide the keyboard if user clears the search-bar.
searchBar.on(searchBarModule.SearchBar.clearEvent, function (args) {
setTimeout(function() {
searchBar.dismissSoftInput();
}, 10);
});
PS
You probably solved your issue, but this could help someone else in the future.
Okay so your problem is a Javascript problem than a NativeScript problem. For the sake of this problem, think of observable arrays as just your ordinary arrays.
In your JS you're creating a new PeopleListViewModel which you're then attaching to the bindingContext via the pageData object. So far so good. Then you're calling the load method on the PeopleListViewModel (It returns a promise which you're not really doing anything with but for this specific problem it doesn't matter).
However, when text is inputed you're not really doing anything. This is your code:
peopleList.filter(function (element, index, array) {
// DOESN"T WORK PROPERLY
console.log("element: ", JSON.stringify(element));
return element.fullName == searchText;
});
peopleList is an instance of PeopleListViewModel which returns an ObservableArray. The ObservableArray does indeed have a method called filter (which works just like filter of a regular array. Check out the NativeScript documentation and Javascript documentation of filter).
What you need to understand here is that filter returns a new array with the filtered results. Doing peopleList.filter() will send that new array into empty space. You want to var yourNewFilteredArray = peopleList.filter(). But you don't really want to redefine the array bound to the binding context, you want to modify the content of it.
Here's an example of how you could do that:
/*
* Attach a new obsersable array to the binding context.
* you can prepopulate it with the data from the
* PeopleListViewModel if you want to
*/
var resultList = new ObservableArray([]);
var pageData = new Observable({ resultList: resultList });
/*
* Then on search/filter you want to modify this new
* array. Here I first remove every item in it and then
* push matching items to it.
*/
searchBar.on("propertyChange", function (args) {
var searchText = args.object.text;
// ...
while(resultList.length > 0) {
resultList.pop();
}
peopleList.forEach(function (element) {
if (element.fullName === searchText) {
resultList.push(element);
}
});
});

How can I remove a single overlay in Openlayers 3.3.0?

I am creating overlays in my mapping application that I need to refresh every 5 seconds. I am only having difficulties removing the stale overlay from my map using the code below. The map.removeOverlay method does not seem to be working correctly. The stacking of the overlays is visibly apparent after only a few iterations.
Using map.getOVerlays().clear() removes the stale overlay, however, this removes all overlays which is not desired. Any assistance with this is appreciated.
window.setInterval(function() {
$.ajaxSetup({ mimeType: "text/plain" });
$.getJSON('json/DATA.json', function(data) {
$.each(data.item, function(key, val) {
var storeName = this.name;
var storeLocation = this.location;
var storeLatitude = this.latitude;
var storeLongitude = this.longitude;
$.each(val.tasks, function(i, j){
var taskName = this.name;
var taskState = this.state;
if (taskState == "Open") {
var taskGeometry = ol.proj.transform([storeLongitude,storeLatitude], 'EPSG:4326', 'EPSG:3857');
function createCircleOutOverlay(position) {
var elem = document.createElement('div');
elem.setAttribute('class', 'circleOut');
return new ol.Overlay({
element: elem,
position: position,
positioning: 'center-center'
});
}
var taskOverlay = createCircleOutOverlay(taskGeometry);
map.removeOverlay(taskOverlay);
map.addOverlay(taskOverlay);
}
});
});
});
}, 5000);
var taskOverlay = createCircleOutOverlay(taskGeometry);
map.removeOverlay(taskOverlay);
The problem is that you are trying to remove the new overlay and not the old one. You would have to store a reference to the overlay so that OpenLayers can remove it from the map. Something like:
var currentOverlay = null;
window.setInterval(function() {
$.ajaxSetup({ mimeType: "text/plain" });
// ...
if (currentOverlay === null) {
map.removeOverlay(currentOverlay);
}
currentOverlay = createCircleOutOverlay(taskGeometry);
map.addOverlay(currentOverlay);
// ...

How to add Handler on Cell in Google Visualization Table in GWT?

Google Visualization API for GWT provides control over rows only.
How to get control over a particular cell in Visualization Table?
selection.isCell() doesn't give true result in any case.
private SelectHandler createSelectHandler(final PieChart chart) {
return new SelectHandler() {
#Override
public void onSelect(SelectEvent event) {
String message = "";
// May be multiple selections.
JsArray<Selection> selections = chart.getSelections();
for (int i = 0; i < selections.length(); i++) {
// add a new line for each selection
message += i == 0 ? "" : "\n";
Selection selection = selections.get(i);
if (selection.isCell()) {
// isCell() returns true if a cell has been selected.
// getRow() returns the row number of the selected cell.
int row = selection.getRow();
// getColumn() returns the column number of the selected cell.
int column = selection.getColumn();
message += "cell " + row + ":" + column + " selected";
} else if (selection.isRow()) {
// isRow() returns true if an entire row has been selected.
// getRow() returns the row number of the selected row.
int row = selection.getRow();
message += "row " + row + " selected";
} else {
// unreachable
message += "Pie chart selections should be either row selections or cell selections.";
message += " Other visualizations support column selections as well.";
}
}
Window.alert(message);
}
};
}
Google Table has 4 events: ready,select,page,sort.
When you sort or paginate, it stops listening the ready event.
To have the cell click working after pagination or sort you need to add the click listener on all of them.
You can use click instead of mouseover.
On select event I use getSelection to be able to get and set the selected row properties.
var colIndex;
google.visualization.events.addListener(table, 'ready', function () {
$("#table").find("td").each(function() {
$(this).mouseover(function(){
colIndex=$(this).index();
});
});
});
google.visualization.events.addListener(table, 'sort', function () {
$("#table").find("td").each(function() {
$(this).mouseover(function(){
colIndex=$(this).index();
});
});
});
google.visualization.events.addListener(table, 'page', function (event) {
$("#tableGoogle").find("td").each(function() {
$(this).mouseover(function(){
colIndex=$(this).index();
});
});
});
google.visualization.events.addListener(table, 'select', function () {
var selection = table.getSelection();
var item;
if(selection.length!=0){
lastSelection=selection;
}
for (var i = 0; i < lastSelection.length; i++) {
item = lastSelection[i];
}
switch (colIndex){
case 0:
data.setValue(item.row,index,true);
// YOUR CODE FOR COLUMN 0
break;
case 1:
var id=data.getRowProperty(item.row, 'id');
// YOUR CODE FOR COLUMN 1
break;
}
});
The Table Visualization does not pass column information in the selection event, so you cannot identify an individual cell this way. You will need to register a click event handler on the cells of the table and then determine the cell's row and column indices. Here's one way to do it using jQuery:
google.visualization.events.addListener(table, 'ready', function () {
$('#table_div td').click(function () {
var column = $(this).index();
var row = $(this).parent().index() - 1; // subtract 1 for the table header
console.log(row, column);
});
});
You'll have to adapt the event handler to the method used in the GWT Viz API package, but the jQuery code should work.
var rowIndex;
var colIndex;
google.visualization.events.addListener(table, 'ready', function () {
jQuery("#table").on("click", "td:not(.google-visualization-table-th)", function() {
colIndex = jQuery(this).index();
rowIndex = jQuery(this).parent().index() - 1;
alert("row "+rowIndex+" col "+colIndex);
//put rest of function here
});
This gets rowindex based on the row of the html. To get the rowindex based on the data (where the row's index won't change even if you sort the table and it's position changes) use
google.visualization.events.addListener(table, 'select', function() {
var selected=table.getChart().getSelection();
var item=selected[0];
rowIndex=item.row;
});
This will run before the code in the .on("click", ...) function in the ready function.