I have create an multi-selectable table which allows you to select multiple rows; however, in order to check the current marking (whether checked OR not) I need to do the following.
Inside the table component,
{{#each rows as |row index|}}
{{table-x-row
row=row
index=index
data=data
selected=(mut selected)
maxSelectionCount=maxSelectionCount
}}
{{/each}}
Inside the table-row JavaScript file,
classNameBindings: ['isSelected:selected'],
isSelected: computed('selected.[]', {
get() {
const index = this.get('index');
const row = this.get('data.rows')[index];
return this.get('selected').includes(row);
}
}),
Code above triggers every time the selected list changes plus for every table-row components which means if I have 10 rows. The computed property will get called for 10 times.
Any suggestion to solve this performance issue?
I have tried to simulate the case you have mentioned in the following twiddle by simplifying the table and row (they are not actual table and rows; but just dummy components to illustrate the case). The computed property within table-x-row is being calculated for every row as you mentioned. This is problematic both in terms of performance and data encapsulation. Passing all the selected array of table-x to every row breaks data encapsulation. Why does individual rows need to know about selection state of other rows (I mean selected attribute of the table)?
In order to avoid that you can crate a computed array property in table-x and pass isSelected information directly to the rows like in the following twiddle. By this way; the computed property rowsWithSelectionInfo defined in table-x is only modified when actual rows change; and nothing is recalculated when a row selection changes. Each individual row is now passed its isSelected property individually and hence does not know about whole data or whole selection info of the table.
Related
I have an igx Grid with sorted rows. The rows are sorted by date (this is a column from the grid). So I have multiple rows with the same date. How can I put a divider between the rows where the date is changed? Here is an example:
Row Date Some stuff
1 01.01.2021 some data
2 01.01.2021 some data
3 01.01.2021 some data
__________________________________________
4 03.01.2021 other data
5 03.01.2021 other data
__________________________________________
So from the 4. row the date is changed, how can I put a divider (something like in this tutorial: https://www.infragistics.com/products/ignite-ui-angular/angular/components/divider) before the 4. row programmatically? How can I do this in Typescript?
Since the Ignite UI for Angular Grid is virtualized and thus its record rendering is entirely data driven, there's no way to inset arbitrary elements in-between rows that I can think of. It'll mess with both rendering/scroll and navigation as you can imagine, so the templatable areas are controlled.
On first glance, your example can probably be achieved with a simple border style through some data manipulation and Conditional Row Styling. You can provide a callback for each row to trigger a class or custom styles.
However, seeing as you already sort by the date it really looks like the scenario you're describing is something that can be handled by Grouping. Group By is already an extension of sorting with the added groups with templatable headers and expand-collapse functionality. Actually, there's an example of this exact type of group under the custom group by example:
What you should be looking at is the expression, the DaySortingStrategy if the default isn't enough, but mostly the groupingComparer which determines if items belong in the same group. Here's a simplified version from the sample:
this.sortingStrategy = DaySortingStrategy.instance(); // or DefaultSortingStrategy.instance()
this.initialExpr = [{
dir: SortingDirection.Asc,
fieldName: 'OrderDate',
ignoreCase: true,
strategy: this.sortingStrategy,
groupingComparer: (a, b) => {
const dateA = this.sortingStrategy.getParsedDate(a);
const dateB = this.sortingStrategy.getParsedDate(b);
return dateA.day === dateB.day && dateA.month === dateB.month ? 0 : -1;
}
}];
which is bound to the Grid's groupingExpressions:
<igx-grid #grid1 [data]="data" [groupingExpressions]="initialExpr">
I suspect the groupingComparer can even be simplified further depending on your data.
I have an interactive grid with a bunch of records, and I want to set up a button on the page that changes one column in all records currently selected.
Running APEX 18.2, the IG has a whole bunch of columns and I want to change just one of them, but on a whole bunch of rows, so I do need a button.
The IG has ROWID as PK because the actual PK is assembled from 4 different columns.
I have spent some time googling this issue and have found a couple people with solutions:
http://thejavaessentials.blogspot.com/2017/03/getting-selected-rows-in-oracle-apex.html
This is the first, and simplest solution. But it doesn't return any rowid or anything like that, it returns the value in the first column.
Then I also found
http://apex-de.blogspot.com/2018/09/update-several-rows-in-tabular-form-grid.html
and
https://ruepprich.wordpress.com/2017/03/23/bulk-updating-interactive-grid-records/
Which are pretty similair and seem to be the best for me, but I get a Javascript error in the console: http://prntscr.com/n5wvqj
And I dont really know much Javascript, so I dont know what went wrong or how to best fix it.
I set up a Dynamic action on button click that executes Javascript and I have the selected element being the region named CUR_STAT.
var record;
//Identify the particular interactive grid
var ig$ = apex.region("CUR_STAT").widget();
//Fetch the model for the interactive grid
var grid = ig$.interactiveGrid("getViews","grid");
//Fetch the model for the interactive grid
var model = ig$.interactiveGrid("getViews","grid").model;
//Fetch selected records
var selectedRecords = apex.region("CUR_STAT").widget().interactiveGrid("getViews","grid").view$.grid("getSelectedRecords");
//Loop through selected records and update value of the AVT_OBR column
for (idx=0; idx < selectedRecords.length; idx++)
{
//Get the record
record = model.getRecord(selectedRecords[idx][0]);
// set Value for column AVT_OBR on "D"
model.setValue(record,"AVT_OBR", 'D');
}
The column named AVT_OBR is a select list with display values(DA, NE) and return values(D, N). But I tried having it be a text field and it didnt help.
I want to be able to select multiple columns and change the data in those entries.
If possible I would also like to be able to change data in such a way in a hidden column. Or if I could get all the ROWIDs for selected records and execute a PLSQL block with them.
Ended up with noone responding so I spent a lot of time and finally came up with a solution.
var g = apex.region('myIG').widget().interactiveGrid('getViews','grid');
var r = g.getSelectedRecords();
for(i = 0; i < r.length; i++) {
g.model.setValue(r[i], 'myColumn', 'Value');
}
For some reason none of the solutions I found had worked. But I learned from those solutions and made this simple piece of code that does what I need.
Also, I was wanting to set up so I could do this set value on a hidden column, I achieved this by just having the column visible and editable, but then when running the page I clicked on the column and hid it, and set the current view as the default report.
If anyone stumbles upon this question, I hope it helps.
I'm newbie in Ember.js framework, and I have a problem, I need a multiple selection of rows in a table. I'm using jQuery Datatables, with Ember-Data, and I need to have an ID of the selected rows, something like push to the array and I have no clue how to do this.
For multiple selection, make sure you initialize the table with the select option set to "multi":
this.$("#myDT").DataTable({
select: "multi"
});
When you want to get the list of all the rows selected, use a jQuery selector to get all the rows that have the selected class and get their data. In this example, the ID is the first column in the data, hence the [0]
var selectedRows = Ember.$('#myDT tbody tr.selected');
var selectedIDs = [];
Ember.$.each(selectedRows, function (i, element) {
selectedIDs.push(table.row(element).data()[0]);
});
You can read more about DataTables API (for things like getting row data using the row.data() method here: https://datatables.net/reference/api/
I have a table component, which receives a model what i call content.
{{my-table content=model }}
This model get sorted into a computed property (CP).
multiSort: Ember.computed.sort('content','sortProperitsWithOrders')
I loop through the multiSort and pass each row to the a row component
{{#each row in multiSort}}
{{my-table-row row=row columns=columns}}
{{/each}}
In each row I have a checkbox component. If it changes, an action is sent up to its parent component (the row component). From the row I send the action further to the table component (action up), where I toggle the row's active property.
The problem: after I use sort, the row lose its active property, and the checkbox is unchecked. Check a checkbox then hit the header of a column.
I would think Ember.compute.sort takes the content and rearrange it based on sortProperitsWithOrders. So if I set the active property on one of the content's item, then I will have it in the multiSort CP. From multiSort it will pass down to the row component, and from the row to the checkbox (data down).
JsBin: http://jsbin.com/mojuquhawo/1/edit?html,js,output
You will find that a new instance of MyTableRowComponent is created for each row each time you sort. When this happens the active property (which originates from MyTableRowComponent) is set to its initial value of false.
See example JSBin showing a new component being created on each sort - look at the console logging.
You need somewhere to store the active property where it persists - the Customer model seems like the most appropriate place.
Also I notice that MyCheckboxComponent is not extending from Ember.Checkbox - instead it's using an Ember.Component - this will likely cause issues as well.
I have created a filter that contains unik values of column:
{
header : 'Вопрос А',
dataIndex: 'answerA',
itemId: 'answerA',
width : 100,
filter: {
type: 'list',
options: this.getStore().collect('answerA'),
},
editor: 'textfield'
}
When the user inputs new value in the cell of the column this value must appear in the filter. How can I do this?
I have looked at Extjs Grid Filter - Dynamic ListFilter but it doesn't help me much.
You should carefully look at StringFilter.js file which is at ux/grid/filter. I did this myself by adding a combobox to each filter. On combo expand I update its store by parsing the corresponding column data. Besides I advise you to collect unique values, for this task use Ext.Array.unique function. Otherwise, if two cells contain the same data both values will go to the store, which is not good, because any of them will produce the same filtration. I do not attach my code, because it is heavily dependent on my custom data types, but the idea is quite easy, I think.