I'm currently trying to create a Microsoft Teams Canvas App using Microsoft PowerApps. Within my App I've got different galleries displaying the data of different data tables. Now I've implemented a confirmation modal for data deletion, but unfortunately I'm not possible to pass the table itself to a context variable to perform a dynamic deletion.
What I've tried is the following:
My deletion trigger for my streams table sets a table identifier and the item to be removed. Also they call the modal:
If(
!IsBlank(_galStreams.Selected);
UpdateContext({
RemoveFrom: 1;
ToRemove: _galStreams.Selected}
);;
Set(ModalActiveRemove;true)
)
The same trigger is existing for a second gallery with another Identifier (2).
Now on my deletion confirmation I've added the following logic to the confirmation symbol:
Switch(
RemoveFrom;
1; Remove(streams; ToRemove);
2; Remove(objectives; ToRemove)
);;
UpdateContext({
ToRemove: Blank();
RemoveFrom: Blank()
});;
Set(ModalActiveRemove; false)
When working with only the streams trigger and table (so only one case) everything is working as supposed. But as soon as I try to use the second trigger, the "ToRemove" item is not identified as part of the second table and I'll receive an incompatible type error.
Is there any way to achieve a correct behavior?
Best regards
Related
So i have created a custom dynamic action that is supposed to run "beforeunload" (in case user closes the tab/browser unexpectedly or navigates away from the page in a manner not intended). This dynamic action runs a simple plsql procedure ( http://prntscr.com/qz0a6c ). A few days ago the Chrome browser updated to version 80 and in this new version "beforeunload" is disallowed and now my dynamic action does not work.
Does anyone have an idea on how I could build this functionality differently? Apex 4.2 is in question.
I guess you are hitting Disallow sync XHR in page dismissal So to turn
your DA to asynchronous one try to set Wait for result property of
your dynamic actions to false.
Here's a complete answer that you should be able to adapt to your situation.
Create a new table to record send beacon data.
create table beacons (
id number generated always as identity primary key,
app_user varchar2(255),
date_sent date,
data varchar2(4000)
);
I used a varchar2 for the data but that could be a CLOB if needed. I'll be passing the data in using the p_clob_01 parameter for Ajax.
Create an Application Process named RECEIVE_BEACON in the Shared Components. Use the following code for the PL/SQL code:
insert into beacons (
app_user,
date_sent,
data
) values (
:APP_USER,
sysdate,
apex_application.g_clob_01
);
Create a Dynamic Action named Window beforeunload. Set Event to Custom, Custom Event to beforeunload, Selection Type to JavaScript Expression, and JavaScript Expression to window.
Select the Action for the Dynamic Action created in step 3. Set the Action to Execute JavaScript Code. Copy/paste the following into the Code field.
var beaconData = {
test: 'value'
};
var formData = new FormData();
formData.append('p_flow_id', '&APP_ID.');
formData.append('p_flow_step_id', '&APP_PAGE_ID.');
formData.append('p_instance', '&APP_SESSION.');
formData.append('p_debug', '');
formData.append('p_request', 'APPLICATION_PROCESS=RECEIVE_BEACON');
formData.append('p_clob_01', JSON.stringify(beaconData));
navigator.sendBeacon('/pls/apex/wwv_flow.ajax', formData);
Save your changes and run the page. Then refresh the page to trigger the Dynamic Action and send the beacon. This example shows how you can send random data from JavaScript but also get session-related data, such as the user name.
i'm trying to create a Form Module where i show how to use the different Trigger Levels in Oracle Forms (I have a blog).
I'm trying the create this scenario:
Have the user update a specific Item (SALES_REP_ID) and show a message (On-Message Trigger) in the Item Level.
Have the user update a another Item (different than SALES_REP_ID) in the same Block(Orders) and show a message in the Block Level.
Have the user update a different Block other than Orders and show a message in the Form Level.
I know this could be done in a different way, but as i said i'm trying the show how the hierarchy in the Form Triggers works.
What i did trying the achieve this:
I created the ON-MESSAGE Trigger with the property: Execution Hierarchy = Override in every level as showed in the image:
enter image description here
For some reason only the trigger in the Form Level is firing even if i change the property Execution Hierarchy to Before or After in all the triggers.
Any suggestion would be highly appreciated.
In case you want to check the issue a bit closer, module is in this Google Drive Link:
https://drive.google.com/file/d/0BzbEh5klWdQdQmJGTDRjRFNULVk/view?usp=sharing
Data Base: ORCL (Sample DataBase), Schema: OE.
I think, you should get rid of all ":System.Message_Level" statements. They may prevent to fire on-message trigger(s) with respect to their level.
There is custom field "Lock Flag" in Account BC, namely in S_ORG_EXT_X table. This field is made available in Opportunity BC using join to above table. The join specification is as follows: Opportunity.Account Id = Account.Id. Account Id is always populated when creating new opportunity. The requirement is that for newly created records in Opportunity BC if "Lock Flag" is equal to 'Y', then we should not allow to create the record and we should show custom error message.
My initial proposal was to use a Runtime Event that is calling Data Validation Manager business service where validation rule is evaluated and error message shown. Assuming that we have to decide whether to write record or not, the logic should be placed in PreWriteRecord event handler as long as WriteRecord have row already commited to database.
The main problem was how to determine if it is new record or updated one. We have WriteRecordNew and WriteRecordUpdated runtime events but they are fired after record is actually written so it doesn't prevent user from saving record. My next approach was to use eScript: write custom code in BusComp_PreWriteRecord server script and call BC's method IsNewRecordPending to determine if it is new record, then check the flag and show error message if needed.
But unfortunately I am faced with another problem. That joined field "Lock Flag" is not populated for newly created opportunity records. Remember we are talking about BC Opportunity and field is placed in S_ORG_EXT_X table. When we create new opportunity we pick account that it belongs to. So it reproduceable: OpportunityBC.GetFieldValue("Lock Flag") returns null for newly created record and returns correct value for the records that was saved previously. For newly created opportunities we have to re-query BC to see "Lock Flag" populated. I have found several documents including Oracle's recomendation to use PreDefaultValue property if we want to display joined field value immediately after record creation. The most suitable expression that I've found was Parent: BCName.FieldName but it is not the case, because active BO is Opportunity and Opportunity BC is the primary one.
Thanks for your patience if you read up to here and finally come my questions:
Is there any way to handle PreWrite event and determine if it is new record or not, without using eScript and BC.IsNewRecordPending method?
How to get value of joined field for newly created record especially in PreWriteRecord event handler?
It is Siebel 8.1
UPDATE: I have found an answer for the first part of my question. Now it seems so simple to me that I am wondering how I haven't done it initially. Here is the solution.
Create Runtime Event triggered on PreWriteRecord. Specify call to Data Validation Manager business service.
In DVM create a ruleset and a rule where condition is
NOT(BCHasRows("Opportunity", "Opportunity", "[Id]='"+[Id]+"'", "AllView"))
That's it. We are searching for record wth the same Row Id. If it is new record there should't be anything in database yet (remember that we are in PreWriteRecord handler) and function returns FALSE. If we are updating some row then we get TRUE. Reversing result with NOT we make DVM raise an error for new records.
As for second part of my question credits goes to #RanjithR who proposed to use PickMap to populate joined field (see below). I have checked that method and it works fine at least when you have appropriate PickMap.
We Siebel developers have used scripting to correctly determine if record is new. One non scripting way you could try is to use RuntimeEvents to set a profileattribute during the BusComp NewRecord event, then check that in the PreWrite event to see if the record is new. However, there is always a chance that user might undo a record, those scenarios are tricky.
Another option, try invokine the BC Method:IsNewRecordPending from RunTime event. I havent tried this.
For the second part of the query, I think you could easily solve your problem using a PickMap.
On Opportunity BC, when your pick Account, just add one more pickmap to pick the Locked flag from Account and set it to the corresponding field on Opportunity BC. When the user picks the Account, he will also pick the lock flag, and your script will work in PreWriteRecord.
May I suggest another solution, again, I haven't tried it.
When new records are created, the field ModificationNumber will be set to 0. Every time you modify it, the ModificationNumber will increment by 1.
Set a DataValidationManager ruleset, trigger it from PreSetFieldValue event of Account field on Opportunity BC. Check for the LockFlag = Y AND (ModificationNumber IS NULL OR ModificationNumber = 0)) and throw error. DVM should throw error when new records are created.
Again, best practices say don't use the ModNumbers. You could set a ProfileAttribute to signal NewRecord, then use that attribute in the DVM. But please remember to clear the value of ProfileAttribute in WriteRecord and UndoRecord.
Let us know how it went !
greetings,I'm facing a problem in Oracle Forms 10g. I created a simple master-detail form where i want to save data only from the detail data block (the master will function more as a browser).
The only solution found till now is to edit the properties of text items in the master block and prevent them from inserting/updating. This comes in conflict with the list of values (LOV) appearing when the user tries to input the app_id, or from a search button (i know that the way is not significant). Is there a way that i can pass values to the primary block and function only as a query?
Any help could save me from lots of trouble!
We can set various properties at the block level using the Block Properties palette. In your case you need to toggle off Delete Allowed, Insert Allowed and Update Allowed. Obviously you will want Query Allowed toggled on.
I've a trigger that detects a change on a field PHONE_EXT and POSTs an EVENT. I would like to post the Phone_ID with the event in order to use this ID in the client. Is this possible? How?
CREATE TRIGGER tr2 FOR employee
ACTIVE AFTER UPDATE POSITION 0
AS
BEGIN
IF (new.PHONE_EXT <> old.PHONE_EXT) THEN
POST_EVENT 'phone_ext_changed'; <-- I would like to pass a string parameter with record ID
END
AFAIK, you cannot pass parameters, but you can get what you want with one of this ideas:
If in your client you're interested in events over specific records, you can append the ID of the changing record and post that event. The clients register the events in which are interested using the specific ID's of interest. See example 1.
if your front-end are interested in all changes but you want to know which particular records changed, you can "flag" the records as "recently changed" (using another field on the same record, or a detail table, for example). Upon client notification and action it reverts or clears the flag. This approach may be powered, for example, using auxiliary tables to track missing records from specific clients, it depends on your needs.
Example 1
begin
if (new.phone_ext <> old.phone_ext) then
post_event 'phone_ext_changed_'||new.ID;
end
Example 2
begin
if (new.phone_ext <> old.phone_ext) then
begin
new.recent_ext_change = 1;
/* or maybe */
new.last_ext_change = cast('now' as DateTime);
/* or maybe */
insert into changed_phone_ext values (gen_id(some_generator, 1), New.ID, 'now');
/* finally, post the event */
post_event 'phone_ext_changed_';
end
end
I'm using both with success in different applications/situations.
You can use it as follows:
Set a context variable in the trigger and place the desired information in it.
Ex.:
Create trigger evento_ai0 for evento
active after insert position 0
AS
BEGIN
Post_Event 'Evento_inserido';
"Creating the context variavble"
rdb$set_context('USER_SESSION', 'REGISTRO' , 'Registro inserido: '||new.eve_id);
END
To capture the saved information use:
Select rdb$get_context('USER_SESSION', 'REGISTRO') from rdb$database;
This is not possible. The event is a name only, if you add ids or other qualifiers, it simply becomes a different event because it has a different name. When subscribing to events, you can only subscribe by name, you can't use wildcards, and it is not possible to include parameters.
Events are for simple and cheap notification, and Firebird can even coalesce multiple 'posts' of the same event into a single notification to a client, so parameters or values are not supported.
The basic idea is that a client subscribe to events, and then determines what changed and what it needs to react to. You can 'help' the client by - for example - populating a support table that is cheap to query.
Also consider reading the article "The Power of Firebird Events", it is a bit old, but a lot of it still applies as Firebird events haven't changed much.