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.
Related
I am using APEX 21.2.
The help says that "Display Only" Items do not store session state value and text fields with "Disabled" attribute set to yes do. But I tried to create an after header computation and set the value of a display only item and it worked. Is it wrong information or am I missing something?
Disabled
Specify whether this item is disabled, which prevents end users from changing the value.
A disabled text item still displays with the same HTML formatting, unlike an item type of Display Only, which removes the HTML formatting. Disabled text items are part of page source, which enables their session state to be evaluated. Conversely, display only items are not stored in session state.
I tried to create an after header computation and set the value of a display only item and it worked
Why wouldn't it work? It is you (a developer) who set it using a computation (which works), but end user can't modify its value as it is set to be display only so - users can just look at item's value.
A computation before rendering is always possible, that has nothing to do with session state. This is about how the item behaves on page submit.
With the "Display Only" item type you can control its behaviour on submit. Behaviour is the same for "Text Field" items that have the "Disabled" property set to on.
I did a quick test with a form on the EMP sample data set. Create a after header computation of type expression :P1_SAL + 1.
Test 1: Setting "set on page submit" on. The form renders with the salary item increased by 1. When page is saved, the new salary is saved for the record
Test 2: Setting "set on page submit" off. The form renders with the salary item increased by 1. When page is saved, the new salary is NOT saved for the record
Where did you see this help text ? I don't see anything about session state.
I have two region one form and one interactive grid like a master detail(company and company contact person ) how i can make the interactive grid mandatory ,the user can't submit page ,he/she need add at least one row in interactive grid ,
I can do that or I need to change the interactive grid to collection and count the row in validation
This one is a little tricky because of the way processes and validations work with Interactive Grids (they are executed once per submitted row). To work around this, I'll use a page item and a validation that works with it.
The basic idea of this solution is based on the fact that a new row will not have a primary key value. Here are the steps to reproduce (my example was on page 14, update the following as needed).
Create an Interactive Grid (IG) region. The primary key column should be Query Only (which ensures it's null for new rows).
Create a Hidden page item named P14_NULL_FOUND. Set Type under Server-side Condition to Never so that it never renders on the page.
Create an After Submit (before Validations) process. This process will NOT be associated with the IG so it will only fire once. Set the PL/SQL Code attribute to:
:P14_NULL_FOUND := 'NO';
That will clear out the value of the page item prior to the next process.
Create another After Submit process that runs just after the previous one. Set Editable Region to the IG. Then set the PL/SQL Code to something like the following:
if :PK_COLUMN_IN_IG is null
then
:P14_NULL_FOUND := 'YES';
end if;
You'll need to replace ":PK_COLUMN_IN_IG" with the name of the primary key column in the IG, such as ":EMPNO". This process will be run once for each submitted row in the IG. If a null value is found for the primary key column, then that would mean the user added a new row and the value of P14_NULL_FOUND would be set to 'YES'.
Create a new validation. This validation will NOT be associated with the IG so it will only fire once. Set Type to PL/SQL Expression. Set PL/SQL Expression to:
:P14_NULL_FOUND != 'NO'
Then set Error Message to something relevant.
At this point, you should be able to run the page and verify that the processes and validation are working correctly.
There is an another solution;
Create a page item like PX_ROWCOUNT which will hold the data of the row count of your IG.
Assign a static ID to your IG region.
Write a JS function to count the rows of the grid then set it to the page item. Sample function;
function f_setRowCount(){
var grid = apex.region("staticIDOfYourIG").widget().interactiveGrid("getViews", "grid");
var model = grid.model;
var rowCount = 0;
model.forEach(function (record) {
rowCount ++;
});
$s("PX_ROWCOUNT",rowCount);
}
To submit your page and run this function, change your submit button's behavior to Defined by Dynamic Action. Execute your function when user clicks to that button then submit your page via DA.
Add validation to Processing section of the page and check your page item there; PLSQL Expression => :PX_ROWCOUNT > 0
The solution by Hamit works nicely, except of the case of deletion of a row.
My suggestion is to amend the above code by adding inside the loop an if statement to check whether the row is editable or no.
So the code will be
var grid = apex.region("staticIDOfYourIG").widget().interactiveGrid("getViews", "grid");
var model = grid.model;
var rowCount = 0;
model.forEach(function (record) {
if (model.allowEdit(record)) {
rowCount ++;
}
});
$s("PX_ROWCOUNT",rowCount);
This is a VERY basic question. Sorry for not providing any code I have NO IDEA how to even start tackling the problem
I have lets say two fields... One is a date selector field and the other a regular text field. What I want is when I select a date (or type a date), the value comes in the second field... Just that...
I'm on APEX 5.1.4
Since you have stated that the second item is a text field, you could do this with the help of a dynamic action that sets the value of the second item when there is a change in the value of the first item ( date field).
The following would be the steps, if you are using component view:
Create Dynamic Action
When
Event : Change
Selection : Item(s)
Item : First Page Item
Condition : is not null
True Action
Action : Set Value
Fire on Page Load: No
Set Type: You can choose how you want to set the value of the second item on the page.
If you have the flexibility to change the second item to be a select list and you have a list of values that goes with a date, you could do this much simpler, with a Cascading LOV
On Second Item's - Under List of Values section
Cascading LOV Parent Item(s) : First Item
Page Items to Submit: First Item
List of Values definition: Here you can define the query.
Hope this helps.
There are a few different ways to do this, probably the easiest way is as follows.
Assume your two items are P1_ITEM1 and P1_ITEM2.
Create a dynamic action which fires on change of item P1_ITEM1.
The true action of this should be action:set value, set type:PL/SQL Expression, item::P1_ITEM2, items to submit P1_ITEM1.
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.
I am new to emberjs and just started using addepar table. I need to add my own customization on click of a row in the table. Could someone please tell how can I override the default click/or row selection operation for the addpar table?
I am trying to achieve to call a new route on click of a row at any column in a row. Render the new route based on the row selected.. say displaying summary and detail of the record. Addepar table displays list of summary of records on click of a row displays in details.
Please let me know the steps to customize on click for entire row selection.
thanks,
eskarthick
To do this you extend Ember Table and override the row view. The row view setting is here, and defaults to Ember.Table.TableRow:
https://github.com/Addepar/ember-table/blob/master/src/component.coffee#L119
The result will look something like this:
App.MyTableComponent = Ember.Table.EmberTableComponent.extend({
tableRowView: 'App.MyTableRow'
});
App.MyTableRow: Ember.Table.TableRow.extend({
click: function() {
// Handle click
}
});
This assumes you really care about the click event. If instead you just want to do something with the row that is selected (or when it is selected), you should use the selection output of the Ember Table API and add computed properties/observers around that. See the docs at:
http://addepar.github.io/ember-table/#/ember-table/documentation