Tabulator: add class to class list, on cells when hidden by pagination - tabulator

I need to add and/or remove a class to all cells even when they are hidden by pagination. I am able to add a class, but only the cells on the active page are getting the class. I understand that is because it is only updating what is available in the DOM and the hidden rows are not active in the DOM at the time, I'm adding the class.
Is there a way that Tabulator handles this?
As you can see from below i'm getting the rows (not shown) and then looping over the rows and attempting to update the cell classList.
for (var i = 0; i < rows.length; i++) {
if (rows[i] != this){
var row = rows[i],
cell = row.getCell(col),
cellElement = cell.getElement();
cellElement.classList.add('disable-cell');
console.log(cell);
}
}

Related

tabulator get column from custom column titleFormatter

I have a custom function that hides/shows columns in my tabulator. The column I click on is supposed to hide and several other columns are shown. I have this function working correctly from onclick on an object in a custom cell formatter, but I would like to call it from clicking on the column header. It works except that I can't seem to get a handle of the column I clicked on from column header in order to hide the column.
I'm trying to get the column object and pass it to my function so I can hide that column while I show the others. I'm open to other ways to do this.
this works (cell formatter)
var showForecastCell = function(cell, formatterParams, onRendered){
...
span.onclick = function(){showForecast(cell.getColumn())};
return span
}
this doesn't work (column titleFormatter)
var showForecastHeader = function(t,e,o,i,n){
...
span.onclick = function(){showForecast(t.getColumn())};
return span
}
Is there any way to pass the column object from clicking on the column header? otherwise, if there is a simpler way to hide the column after clicking on the header, I am open to suggestions. I must admit that javascript isn't my strongest language and if I am overlooking something basic, please let me know.
You can check this JsFiddle it hides all other columns except the one you click
for Column call backs you can check documentation here and here
const hideAllButThis = function(e, column) {
const showField = column._column.field;
const columns = column._column.table.columnManager.columns;
for (let i = 0; i < columns.length; i++) {
if (columns[i].field !== showField) {
table.hideColumn("" + columns[i].field + "")
}
}
};

How to click on an exact row on wintable with codedui?

I want to click on an exact row in a WinTable where my criteria meets but couldnt succeed so far. I can search criteria for an exact row but I can not get total number of rows so that I would make a loop for all rows. I tried collection and table.Rows.Count,but both brings nothing to me. Can someone help me on this ?
#region Variable Declarations
WinTable uIG1Table = this.UIProMANAGEWindow.UIDefinitionsWindow.UIG1Window.UIG1Table;
WinRow dataGridrow = uIG1Table.GetRow(0);
#endregion
UITestControlCollection rows = uIG1Table.Rows;
// MessageBox.Show(rows[5].RowIndex.ToString());
foreach (WinRow row in uIG1Table.Rows)
{
foreach (WinCell cell in row.Cells)
{
if (cell.Value.ToString() == "E81")
Mouse.Click(cell, new Point(5, 0));
}
}
and this is the code with for loop
int rows = uIG1Table.Rows.Count;
for (int i = 0; i < rows; i++)
{
foreach (WinCell cell in dataGridrow.Cells)
{
if (cell.Value.ToString() == "E81")
Mouse.Click(cell, new Point(5, 0));
}
}
When doing a GetChildren() on a row, you will notice that the first child is of type RowHeader. A user typically clicks the row header to select the row.
Following code will iterate all the rows in a DataGridView and click the row header, effectively selecting the row:
UITestControlCollection rows = YourUIMapTable.Rows;
foreach (UITestControl row in rows)
{
UITestControl rowHeader = row.GetChildren().Single(child => child.ControlType == ControlType.RowHeader);
Mouse.Click(rowHeader);
}
If you want to select a specific row, you can do something like this:
Mouse.Click(YourUIMapTable.Rows[putIndexNumberHere].GetChildren().Single(child => child.ControlType == ControlType.RowHeader));
The sample code above is based on the program I wrote in my answer to this question:
How to get cell color information of a WinCell with codedui?

JQuery in VirtualDOM Buffer Rows

I have a column of checkboxes in my table that I want to have checked with parity in row.isSelected().
When using the VirtualDOM the rows in the buffer don't get checked/unchecked as part of a table.getRows() loop to un-check the box. The rows DO get unselected from the table POV via row.deselect().
The checkbox is added with a mutator to the first column:
checkboxMutator = function (value, data) {
return '<input type="checkbox" class="rowCheckBox" name="' + value + '">';
}
The select all logic:
$("#select-all").click(function () {
var rows = table.getRows(true);
rows.forEach(function(row){
row.select();
$("input[name='" + row.getData().index + "']:checkbox").prop('checked', true);
});
});
The rows that don't exist in the DOM at all yet can be checked by adding some logic into rowFormatter to check them on render the first time.
It might not be possible to fix, but I thought it was worth asking about.
Because Tabulator uses a vitrual DOM only the rows that are visible actually exists, rows are created and destroyed as you scroll.
Because of this it is not safe to try and manipulate any DOM elements inside the table from outside.
In your case you should be using a Custom Formatter that uses the isSelected function on the row component to determine if the checkbox should be selected when it is created.
//custom formatter
function checkboxFormatter(cell, formatterParams, onRendered){
//create input element
var input = document.createElement("input");
input.setAttribute("type", "checkbox");
//set checked state
input.checked = cell.getRow().isSelected();
return input;
}
//assign formatter in column definition
{title:"selected?", formatter:checkboxFormatter}
You should then be using the rowSelectionChanged option to redraw the row after selection has changed, which will then cause the formatter to run and update the checkbox.
rowSelectionChanged:function(data, rows){
//rows - array of row components for the selected rows in order of selection
//data - array of data objects for the selected rows in order of selection
//reformat all rows that have changed
rows.forEach(function(row){
row.reformat();
})
}
You can then select all rows in the table by calling the selectRow function on the table.
table.selectRow();

CodedUI "FindMatchingControls()" works 10% of the time but usually returns about half of the controls

Problem: I am using FindMatchingControls() to create a Collection of rows in a WPF table. I have written a loop that will set the ComboBox in each row to a given value. The whole thing works sometimes but more often than not, FindMatchingControls() actually finds about half of the rows. How can I configure timeouts or change settings to make it find all 50 controls every time or perhaps to find the first 10 and then to find the next 10 etc?
Background: I am testing a WPF window and on it, there's a table, each row in the table has a drop down list. There are 50 rows and in future there could be more so it is not feasible for me to record the setting of each one, my recorded test would be out of date with each new version (every month or so).
I have therefore recorded the setting of 1 ComboBox and then I used FindMatchingControls() to create a Collection. I loop through the Collection setting each ComboBox in that collection to the desired selection. The first 23 rows are shown on my current screen resolution. The only problem is that FindMatchingControls() sometimes returns 23, sometimes 26 , sometimes 34 and sometimes it returns all 50 rows! My question is, how do I fix the code below so that it always return all 50 rows (and possibly more in future).
You can see from the code that I found the Parent control twice so pseudo code is below.
Psuedo Code:
1) Find Parent Container (table)
2) Define a row (that is a child of the parent table)
3) Use FindMatchingControls to get a Collection of Rows
4) Loop through the Collection, finding the ComboBox in each row and setting it's selection to a value passed into the method.
CODE:
public void PlaceAnOrderScreen_SelectItems_List(String item /*Value to set all 50 ComboBoxes to*/)
{
WpfControl rowOfOrderItems = new WpfControl(this.UIOptimalOrderSystemClientShWindow.UIItemCustom22.UIListViewAutoID37Table);
rowOfOrderItems.SearchProperties[WpfControl.PropertyNames.ControlType] = "DataItem";
rowOfOrderItems.SearchProperties[WpfControl.PropertyNames.ClassName] = "Uia.ListViewItem";
rowOfOrderItems.WindowTitles.Add("Order Management System");
rowOfOrderItems.Find();
rowOfOrderItems.DrawHighlight(); //Visible diagnostic
//should get a collection of 50 controls ...
//... but this is dodgy, it sometimes finds 23, 26, 34 or ocassionaly all 50 controls.
//There are 23 visible controls and the rest, you have to scroll down to see.
UITestControlCollection itemRows = rowOfOrderItems.FindMatchingControls();
int c = 0;
int i = 1;
string label = String.Empty;
foreach (var auditSelectionBox in itemRows)
{
//After the top 15 drop down selections have been made, strat scrolling down.
//This is because setting the Value for a list box that is off the screen
//causes it to complain the control is blocked...
if (c >= 15)
{
if (i >= 3) //The scroll wheel moves 3 rows at a time, so only scroll once for every 3 rows...
{
Mouse.MoveScrollWheel(-1);
i = 0;
}
}
i++;
c++;
WpfCell auditDDL1 = new WpfCell(auditSelectionBox);
auditDDL1.SearchProperties[WpfCell.PropertyNames.ColumnHeader] = "Total";
auditDDL1.WindowTitles.Add("OrderSystem 5");
//Works but takes 5 - 16 seconds per drop down list
auditDDL1.Value = item;
}
}
Instead of trying to find matching controls based on another row, you could use a method that takes the parent (in your case the table) and returns all it's children in a recursive way. It digs all the way down until all available children have been found. It shouldn't matter how much row's your table has, it will try and get all of them. It's usable for any UITestControl.
public ParentControl GetChildControls(UITestControl parentControl)
{
ParentControl parent = new ParentControl();
if (parentControl != null)
{
List<ParentControl> children = new List<ParentControl>();
foreach (UITestControl childControl in parentControl.GetChildren())
{
children.Add(GetChildControls(childControl));
}
parent.Children = new KeyValuePair<UITestControl, List<ParentControl>>(parentControl, children);
}
return parent;
}
The parent class
public class ParentControl
{
public KeyValuePair<UITestControl, List<ParentControl>> Children { get; set; }
public string Value
{
get
{
return Children.Key.Name;
}
}
}
I just added the Value property for easy access to the name of UITestControl.
PixelPlex (above) has provided the best answer. All I had to add to PixelPlex's code was an If statement to set the ComboBox to a value when it was found. The foreach is therefore as below in my case ...
foreach (UITestControl childControl in parentControl.GetChildren())
{
children.Add(GetChildControls(childControl));
//Added below If statement to set ComboBox selected item to "Carrots"...
if (childControl.ClassName == "Uia.ComboBox")
{
WpfComboBox cb = (WpfComboBox)childControl;
cb.SelectedItem = "Carrots";
}
}
This selects Carrots from my ComboBox... Everything that does not satisfy my If statement is not relevant so I don't do anything with it.

Ignite UI export to excel table with multi-column header

I am using Ignite UI in my website to view the table and i need to export it to excel. I am using default Infragistricts functionality $.ig.GridExcelExporter.exportGrid, but i get table with only lower part of header. I have multi-column header, and i get only the lower part. Is there a way to fix it?
the igGridExcelExporter does not handle the MultiColumnHeaders. Also, the grid is exported into a table region inside the worksheet, which does not allow cell merging. This means that you can imitate a multi header by inserting a new row and merging cells in the exportEnding event:
exportEnding: function(sender, args) {
args.worksheet.rows().insert(0, 1); // insert one new row at index 0
//create a merged cells region that will act as a multi header
var mergedHeaderRegion = args.worksheet.mergedCellsRegions().add(0,1,0,2); // firstRowIndex, firstColumnIndex, lastRowIndex, lastColumnIndex
mergedHeaderRegion.value("Month1");
// style the newly inserted row as a header
for (var columnIndex = 0; columnIndex < 4; columnIndex++) {
args.worksheet.rows(0).getCellFormat(columnIndex).fill($.ig.excel.CellFill.createSolidFill("rgb(136, 136, 136)"));
args.worksheet.rows(0).getCellFormat(columnIndex).font().colorInfo(new $.ig.excel.WorkbookColorInfo("rgb(255, 255, 255)")); }
}
You can also refer to the following help topics and API docs:
http://www.igniteui.com/help/javascript-excel-library-merge-cells
http://help.infragistics.com/jQuery/2015.2/

Resources