I have multiple Ignite UI grids setup on a page. The grid has excel export feature but it only works for the current grid. How can I export all the grids at a single event?
Any grid events to be captured or modified.
I am using 2016 v2 release
After researching for multiple options, found a solution which does a sequential walk through of the grid collection and appends each one to the main workbook.
For exportEnding method of 1st grid you chose, call a function which does the export (suppose to) for the 2nd grid. This can be sequenced for as many grids as required. Let say each such function is named as ExportGrid, eg exportSecondGrid.
grid1's
exportEnding :function(sender, args) {
exportSecondGrid(args.workbook);
return false;
}
Use the grid 2's headerExporting event to append the current worksheet to the main workbook. Its exportEnding takes the header collection generated in header exporting to manually set for the worksheet
Now the grid 2's events as below
var headerArr = [];
$.ig.GridExcelExporter.exportGrid($("#gridSecond"), {
fileName: fileNamePassedAsParameter,
worksheetName: Sheet2NamePassedAsParameter
},
{
headerCellExporting: function(sender, args) {
// We will save all the headers coming to our array for retrieval later on
headerArr.push(args.headerText);
if (args.columnIndex === 0) {
sender._workbook = workbook;
sender._workbook.worksheets().add( sender._worksheet.name());
sender._worksheet = sender._workbook.worksheets(1);
}
},
exportEnding: function(sender, args) {
// Now use the array of headers to be updated
var row = sender._worksheet.rows(0);
for(var ind=0; ind < headerArr.length; ind++) {
row.setCellValue(ind, headerArr[ind]);
}
}
}
);
}
Related
Can I use NSArrayController for my tableview , and using simultaneously this method : ?
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any?
The idea behind:
I do not want to loose the benefits of the arraycontroller ( insert, update, delete ...) but I would like to have control on additional columns to display. The information inside these columns are calculated and formatted; values are coming from the array that the arraycontroller manages (Core Data).
I am afraid this is not possible because controller and tableviewfunction excludes each other ...
Thanks to Willeke, I got it made finally by using a extension for my entity.
extension ImportLog {
// Splits the imported lines into individual words
// For each entity, I split the property "line" .
// Later, in the objc computed property, I pick column number x
var splittedText:[String.SubSequence]{
return(self.line!.split(separator: ";"))
}
// col1
#objc var f1: String {
get {
let theColumn = 0
var text:String = ""
if ( splittedText.count-1 >= theColumn) {
text = String(splittedText[theColumn])
}
return text
}
set {
// no need to set something
}
}
}
The computed property "f1" of the entity can now be bound in the XIB file
by "Table Cell View.objectValue.f1"
I have created one dojo datagrid. Every column has a formatter attached to it. When grid is generated the formatter is called. Now I want it so that if a user selects any row the formatter will be called and some strings should be attached to the selected row's column element.
Like grid is like this :
COLUMN
-------
a
b
c
and now user selects the 2nd row, the grid should change to :
COLUMN
-------
a
b SELECTED
c
Currently I implemented it like this :
if(this.grid.selection.selectedIndex !== -1){
retrun value + "SELECTED";
}else{
return value;
}
Can you please suggest a some good way of doing this? Please note that "SELECTED" string should not be added to the grid store.
The formatted is not hooked into clicking / selection of rows. It is solely performed when the contents (value) of a cell is set. Instead you'd want to move focus over to onRowClicked - an event on the grid component. It works like this:
grid.onRowClick = onRowClickHandler;
I wouldnt know which of following samples would put you closest to your goal but onRowClickHandler could be setup as such:
function onRowClickHandler(evt) {
var rows = this.selection.getSelected();
// perform cell rendering here
dojo.forEach(rows, function(row) {
// this row is an item though.. you will have row._O as its index
});
}
OR
function onRowClickHandler(e) {
var cellClicked = this.focus.cell
cellClicked.formatter();
}
However you may find that there are not much references to the viewable data anywhere in the grid component.. You could use following query selectors to find cell data and update the viewed html by calling formatter on each value. You would need to capture a previous selection for 'teardown' of your custom setting of values though.
var prevSelectedRows = [];
function onRowClickHandler(evt) {
var idx = this.selection.selectedIndex,
rawRow = dojo.query(".dojoxGridRow:nth-child("+(idx+1)+")", this.domNode)[0],
self = this;
// perform resetting of viewable values
dojo.forEach(prevSelectedRows, function(raw) {
dojo.query('.dojoxGridCell', raw).forEach(function(cellDOM, i) {
cellDOM.innerHTML = cellDOM.innerHTML.replace("SELECTED", "");
});
});
prevSelectedRows = []; // reset prev selection
// look into grid.view.content for methods on this
// perform setting of viewable values (SELECTED)
dojo.query('.dojoxGridCell', rawRow).forEach(function(cellDOM, i) {
// this function might be of interest, lets see how it looks in console
console.log(self.layout.cells[i].formatter);
cellDOM.innerHTML = cellDOM.innerHTML + "SELECTED"
});
prevSelectedRows.push(rawRow);
}
I need to push real time data to a Flex GUI (Data grid), but each time new data is pushed to the grid, it's losing its previous state.
Example:
if I scrolled to the right, after the next update scrolls come back to the default position, that is, left
if I am selecting any row, it's getting unselected just after update.
Is there a way to maintain the state?
I am using Flex 3. I can move to Flex 4 if it helps.
How do you set the data? Do you change the DataGrid dataProvider with a new collection of objects ? Because, from the behavior described by you this may be the case.
The solution would be instead changing the dataProvider of the DG. Each time, you should just update the values in the collection which is assigned as data provider.
For example,
[Bindable]
var myDataCollection:ArrayCollection = new ArrayCollection([0,1,2,3,4]);
// Handle creation complete.
private function onCreationComplete():void
{
initDG();
}
// Init DG data provider just once.
private function initDG(data:ArraCollection):void
{
myDG.dataProvider = data;
}
private function updateDG_Method_1(row:int, value:int):void
{
var data:ArrayCollection = myDG.dataProvider as ArrayCollection;
if(data && data.length > row)
{
data[row] = value;
}
// We can force refresh if not not done automatically.
myDG.invalidateList();
myDG.validateNow();
}
private function updateDG_Method_2(row:int, value:int):void
{
if(myDataCollection && myDataCollection.length > row)
{
myDataCollection[row] = value;
}
// We can force refresh if not not done automatically.
myDG.invalidateList();
myDG.validateNow();
}
Please ignore/correct any typo .. since I did not test this :))
Good luck!
So this is driving me crazy. I've got an advanced data grid with a dataprovider that's an array collection w/ hierarchical data. Each object (including the children) has an id field. I'm trying to drag and drop data from within the ADG. When this happens, I need to grab the id off the drop target and change the dragged object's parentid field. Here's what I've got:
public function topAccountsGrid_dragDropHandler(event:DragEvent):void{
//In this function, you need to make the move, update the field in salesforce, and refresh the salesforce data...
if(checkActivateAccountManageMode.selected == true) {
var dragObj:Array = event.dragSource.dataForFormat("treeDataGridItems") as Array;
var newParentId:String = event.currentTarget['Id'];
dragObj[0].ParentId = newParentId;
} else {
return;
}
app.wrapper.save(dragObj[0],
new mx.rpc.Responder(
function():void {
refreshData();
},
function():void{_status = "apex error!";}
)
);
}
I can access the data I'm draggin (hence changing parentId) but not the currentTarget. I think the hierarchical data is part of the problem, but I can't find much in the documentation? Any thoughts?
event.currentTarget is not a node, it's the ADG itself. However, it's quite easy to get the information you want, since the ADG stores that data internally (as mx_internal).
I'm using the following code snippets (tested with Flex SDK 4.1) in a dragOver handler, but I guess it will work in a dragDrop handler too.
protected function myGrid_dragDropHandler(event:DragEvent):void
{
// Get the dragged items. This could either be an Array, a Vector or NULL.
var draggedItems:Object = getDraggedItems(event.dragSource);
if (!draggedItems)
return;
// That's our ADG where the event handler is registered.
var dropTarget:AdvancedDataGrid = AdvancedDataGrid(event.currentTarget);
// Get the internal information about the dropTarget from the ADG.
var dropData:Object = mx_internal::dropTarget._dropData;
// In case the dataProvider is hierarchical, get the internal hierarchicalData aka rootModel.
var hierarchicalData:IHierarchicalData = dropTarget.mx_internal::_rootModel;
var targetParent:Object = null;
// If it's a hierarchical data structure and the dropData could be retrieved
// then get the parent node to which the draggedItems are going to be added.
if (hierarchicalData && dropData)
targetParent = dropData.parent;
for each (var draggedItem:Object in draggedItems)
{
// do something with the draggedItem
}
}
protected function getDraggedItems(dragSource:DragSource):Object
{
if (dragSource.hasFormat("treeDataGridItems"))
return dragSource.dataForFormat("treeDataGridItems") as Array;
if (dragSource.hasFormat("items"))
return dragSource.dataForFormat("items") as Array;
if (dragSource.hasFormat("itemsByIndex"))
return dragSource.dataForFormat("itemsByIndex") as Vector.<Object>;
return null;
}
var dropData:Object = mx_internal::dropTarget._dropData;
should be
var dropData:Object = dropTarget.mx_internal::_dropData;
Try this.
I'm trying to use a System.Windows.Forms.DataGrid control in my Compact Framework 3.5 Window Mobile Professional 6 SDK based project to show some properties of objects of type Something by binding the DataGrid to a List<SomethingWrapper> instance like this:
public class SomethingWrapper {
private Something data;
public SomethingWrapper(Something data) { this.data = data; }
public string Column1 { get { /* string from this.data */ } }
public string Column2 { get { /* string from this.data */ } }
}
public class SomethingList : List<SomethingWrapper> {
public SomethingList(IEnumerable<Something> items) {
foreach (var item in items) Add(new SomethingWrapper(item));
Sort((a, b) => a.Column2.CompareTo(b.Column2);
}
}
/* ... */
IEnumerable<Something> dataToShow = /* assume this is filled correctly */
SomethingDataGrid.DataSource = new SomethingList(dataToShow);
This seems to work fine: the correct data is shown in the grid with two columns called Column1 and Column2 and sorted on the second column. I want this to be a readonly view of this data, so all is fine.
However, I would like to set column widths and cannot seem to get this to work...
Have tried to obvious: creating TableStyle, creating textbox column style instance per column, adding it to the TableStyle and setting SomethingDataGrid.TableStyle to resulting table style. (This is from memory, or I would also show the exact code I'm using. If needed, I can add that to the question somewhere later today.)
Nothing changes however. I suspect this has something to do with the MappingName on the TableStyle object; all examples I could find yesterday evening seem to be for databinding a DataSet to the DataGrid and setting MappingName to the correct table name in the DataSet. Otherwise, the table style will not do what you expect, which is the behavior I'm seeing.
Question: am I looking in the correct place for a solution to my problem, and if so, what do I need to set TableStyle.MappingName to when binding to a List<T> to show properties of T...?
(Tried to check for possible duplicates, but was unable to find exact matches. Please correct me if I turn out to be wrong there.)
Ah, didn't look well enough after all: duplicate question found. Will try deriving from BindingList<T> and/or using a binding source so I can start calling BindingSource.GetListName(null) to get a MappingName. Hope this will help. If not, I'll be back...
You can do this by creating a DataGridTableStyle
Here is an extension method that I use:
public static void SetColumnStyles<T>(this DataGrid ctrl, T data, params ColumnStyle[] column) where T: class
{
var ts = new DataGridTableStyle();
ts.MappingName = data.GetType().Name;
foreach (var style in column)
{
ts.GridColumnStyles.AddColumn(style.Header, style.Column, style.Width);
}
ctrl.TableStyles.Clear();
ctrl.TableStyles.Add(ts);
}
Then I call it like this:
var newList = queriableData.ToList();
ProductEdit.DataSource = newList;
ProductEdit.SetColumnStyles(newList, new[]
{
new ColumnStyle("Name", 200),
new ColumnStyle("Manufacturer", 100),
new ColumnStyle("Size", 20)
});
where newList is a generic list of objects.