Reputation: 363
I am using Oracle Apex 18.2.
I have an interactive grid and a custom button to add a new row to the IG using,
apex.region("myRegionStaticId").widget().interactiveGrid('getActions').invoke('row-add-row');
then set a column's value using, $s("myColumnStaticId","2");
. When I try it, it adds the first row without setting any columns' values and starts setting the value from the second row on. Even using selection-add-row
or insert-record
, there is always something with the first row. Here is a sample,
[https://apex.oracle.com][1]
ws = ESLAM_WS
user = forhelp
pwd = forhelppwd
app = TEST
page = Add Row on top of an IG.
Upvotes: 0
Views: 6806
Reputation: 42
const
widget = apex.region("staticRegionId").widget(),
view = widget.interactiveGrid("getCurrentView"),
model = widget.interactiveGrid("getViews","grid").model,
selection = view.getSelectedRecords(),
recId = model.insertNewRecord(undefined,selection[selection.length-1]);
model.setRecordValue(recId,'DESCR','Your Description Here');
Notes (see also Oracle Apex docs):
Upvotes: 0
Reputation: 4659
After a lot of talking and testing, I've found that $s
with setTimeout
isn't very reliable. I've set up page 7 again to demonstrate.
setValue
returns), the second row will not be initialized. I'll show you a workaround for this below, but you'llsetTimeout
to, say, 10 ms, and try focusing in the Expiry Date column before clicking the Rowaddrow button, you'll find it doesn't work. This means that, while the setTimeout
of 100 ms works now, it could break in the future if the IGs internal logic changed. Unlikely but who knows. For the moment, I would say that $s
can only be reliably used to set a column value in an IG for the active row. When the row-add-row action adds a new record, it does make it active, but that is done asynchronously via setTimeout
. This is because the IG is based on the flyweight pattern and there are a number of async (setTimeout
based) heuristics that are built in to handle focus and blur events to correctly enable and disable rows and cells as needed.
I've found the following to be the most reliable solution. Unfortunately, it's more complex than what you had before - but it was the only way I could wrangle it all together. Feel free to use it or not. See page 8 for an example.
Right-click the custom Rowaddrow button and select Create Dynamic Action. Set the Name of the DA to rowAddRow button clicked. The When settings will automatically be configured for the click event on the button.
Select the action for the new DA. Set Action to Execute JavaScript and enter the following JavaScript in the Code attribute.
addRowClicked = true; // Global used to distinguish custom button click
this.triggeringElement.disabled = true; // Disable button to serialize access
apex.region("KITCHEN_SHARE_DTL").widget().interactiveGrid("getActions").invoke("row-add-row");
Create a new Dynamic Action and set the Name to New row initialized. In the When section, set Event to Row Initialization [Interactive Grid], Section Type to Region, and Region to KITCHEN_SHARE_DTL.
Under Client-Side Condition, set Type to JavaScript expression and enter the following code in JavaScript Expression (which ensures the DA only fires for the click of the Rowaddrow button):
addRowClicked === true
Select the action for the new DA. Set Action to Set Value, Set Type to Static Assignment, and Value to 2. In Affected Elements, set Section Type to Column(s) and Column(s) to INGREDIENT_ID. This will replace the static assignment that was being done with $s
. Ensure that Fire on Initialization is disabled.
Right-click the True branch for the DA and select Create TRUE Action. Set the Action to Set Value, Set Type to SQL Statement, and enter the following code in SQL Statement:
select MIN(EXPIRY_DATE) from stock
where ingredient_id = TO_NUMBER(:INGREDIENT_ID);
Set Items to Submit to INGREDIENT_ID and disable Escape Special Characters. In Affected Elements, set Selection Type to Column(s) and Column(s) to EXPIRY_DATE. Ensure that Fire on Initialization is disabled.
Right-click the True branch for the DA and select Create TRUE Action. Set Action to Execute JavaScript Code and enter the following JavaScript in the Code attribute.
addRowClicked = false; // Unset the global
$x('ADD').disabled = false; // Enable the button
Upvotes: 1
Reputation: 371
Change the following code:
$s("INGREDIENT_ID","2");
with the following one:
setTimeout(function(){ $s("INGREDIENT_ID","2"); }, 100);
It seems that the IG needs a little time to render the new row before you are able to change any value.
Upvotes: 0