Everytime my page comes up it executes the table query. I tried doing this,
https://blogs.oracle.com/shay/entry/preventing_queries_when_page_f
but it still happens. How can I fix this? I've tried setting the refresh condition to never, but then I can't get any data back. I'm using JDev 11g.
Thanks.
I can share how I did this in JDeveloper 12.1. I am not sure whether it works in 11g. Nor am I sure it's the best way to do it. But it worked for me.
The idea is to not prevent the initial query execution, but, rather, to make sure it happens quickly and returns no data. The approach is to set the initial query criteria in the View Instance of your Application Module.
This approach assumes you have at least one bind variable in your view object. If you do not, you will need to add one just for this.
Double click on the Application Module
Click on the "Overview" tab at the bottom
Click on the "Data Model" tab on the left, so that you are viewing the Data Model Components of your Application Module
In the "Data Model" tree on the right, click once on the View Object Usage ("MyObjectVO1", e.g.).
Click the "Edit..." in the upper-right corner of the Data Model tree.
Here, you can specify view criteria to be used initially for the page. So,
* Set an initial parameter that will (A) execute quickly and (B) return no data
Then, later, programatically reset the bind variables to correct values that will return data, when you are ready to let your query run.
The most simple way i know is to set up correctly "Refresh" attribute on iterator in the page definition.
To do that set refresh=ifNeeded, then set RefreshCondition with expression language, something like this: #{viewScope.yourBean.refresh}
public class YourBeanClass {
private boolean refresh = false;
public void someAction(ActionEvent actionEvent) {
//some custom logic to set refresh flag
refresh = true;
}
public boolean isRefresh() {
return refresh();
}
}
With this code you can simply manage the moment when you need to refresh your model.
While these solutions will work to prevent the query from executing, I would ask what is the use case that a user sees a table appear on a web page without doing a search first?
ADF is built to query automatically because normally a web page will have an af:query or af:quickquery component on the page to allow the user to enter a query. Once the query is executed, the results are returned and populate the table or form (depending on the page design). Including either of these search components on the page will prevent the page from executing the query until the search is executed. You can also execute a query on entry to the page using a taskflow and adding an Execute operation from the data control to the navigation into/prior to getting to the page.
Note that Shay's blog post is from 2009 and covers the use case of not using a search component and instead uses Execute with Params. Is this what you are using? Saying more about your use case would be helpful.
Related
I am writing a simple App Inventor program to populate a Covid-19 school health check page. I am stuck on selecting a school. Normally you type in a school name, the page finds string matches and you select from the list of string matched school. I am able to simply set the field manually but the rest of the form doesn't update. I know I must trigger an update but I cannot make head or tails of how this page works.
image of school selection
typing in part of school name
From the Chrome console I can do the following:
x = document.getElementsByClassName("k-textbox")
x[1].value = "Horace"
From the picture you can see the text was updated to "Horace" but the results have not updated. What should I do to force an update so the results list shows proper matches? Also, how do I query the matching results so I can confirm that my input was explicit enough to return a single match? FYI, this form entry page will be hidden to the user.
You can get the kendoDropDownList, call the read method from it's dataSource, and pass the locationName value of what you want. This won't set the text in the textbox, but it will filter your list down like you want.
To test, click on the input, open your console, and run the following:
$('#Location').data('kendoDropDownList').dataSource.read({ locationName: 'horace' })
I am trying to set a value of a page element on page load in the beginning.
The value is dependent on another element that has already been retrieved from the DB and is already set at the beginning.
To set the id I created a function and I call this function for the dynamic action on page load like this:
declare
id number;
begin
id:= set_ID(V('P1_page_item'));
apex_util.set_session_state('P17_ID',id);
end;
However the value for the page item is not being set.
Do you have any suggestions how an page item value can be set on page load?
There are many ways to set the value of a page item on page load. You can use a page process, a computation, a default value for the page item or a source value for the page item. A dynamic action is a possibility as well, but I have never done that...
Personally I find a computation the cleanest way of setting a value to a page item. It is meant just for that - computing a value for an item. In your case, you could create a computation for item P17_ID of type expression with source set_ID(:P1_PAGE_ITEM)
Now the problem of the page item not being set is probably something else. Try to give as much information as possible about the page to give us clues as to why this is not being set correctly. Have you run the page in debug ? That should give you an idea of what is happening.
On a side note:
The function V should not be used in an application. It was created to allow referencing of apex item values outside of the context of an application, for example in a stored procedure or a view. Using the V function has performance issues and should be avoided if possible. In the application, just use the bind variable syntax (:P1_ITEM) to reference and set variable values.
How is P1_PAGE_ITEM being set ? As a best practice try to avoid referencing page items on other pages. P1_PAGE_ITEM should only be referenced and manipulated on page 1 and so on. Using branches or links you'd then set a corresponding item P17_PAGE_ITEM on page 17. This will save you a lot of debugging time later on. Also, if you clear cache on page 1, then the value of P1_PAGE_ITEM will be wiped out which could lead to unexpected behaviour if that page item exists on other pages.
I'd use
id := set_ID(:P1_PAGE_ITEM);
Also, did you set dynamic action to fire on initialization? I presume you should.
I currently have a validation rule that prevents user from making changes to a record when its status is completed. Users are only allowed to make changes if the status is either draft or registered.
AND(
TEXT(Current_Status__c) <> "Draft",
TEXT(Current_Status__c) <> "Registered"
)
There is a new requirement to allow user to update only a specific picklist value field even if the record status is completed. If i remove the validation rule, user will be able to change any fields on the page layout which won't work.
Object setting for the profile is read, create, edit. This object is a child object to Opportunity, OWD is controlled by parent.
Any recommendation on how to solve this issue ?
Thanks in advance.
We can rewrite your rule as ISPICKVAL(Current_Status__c, 'Completed') for example, looks bit cleaner. Your call though, you can keep as is.
So what you'd need is something like ISPICKVAL(Current_Status__c, 'Completed') && !ISCHANGED(Some_Picklist__c). It should let the edit through if you're modifying that picklist.
The problem is it won't check if that's the only change. Usercan cheat, modify 10 fields and they'll "piggyback" and save OK as long as one of them is that picklist.
It's pain to write validation like ISPICKVAL(Current_Status__c, 'Completed') && !ISCHANGED(Some_Picklist__c) && (ISCHANGED(Field1__c) || ISCHANGED(Field2__c) || ISCHANGED(Field3__c)). You'd have to add all editable fields to it, change it every time you make new one. And eventually you'll hit length limits.
I know 3 options for this if it's a concern for you:
Ask a developer to rewrite your logic to Apex trigger, it could then go dynamic through all fields (using "describe" calls to learn field names or stuff like getPopulatedFieldsAsMap.
Another trick is to allow editing completed records only through a quick action, not normal edit page. In that action you could set some hidden checkbox in the field prepopulating step and your validation would let the save through only if that checkbox is set. But then you need to deactivate it somehow anyway or the bypass will get permamently enabled.
If you don't have too many record types on the object a common trick is to change the record type on completion (workflow, process builder etc). And have another page layout with all fields locked down except that special picklist. It works good enough for UI changes but won't protect if you have code and integrations writing to the object too.
Yo! As the topic says, I need to keep var's value through refresh. Thing is it's SessionKey. Other thing is it's generated automatically.
What I need to do is html <select> which won't lose data on refresh. Actually there're 2 <select>s which are filled programatically and you can pass data between them in real time. Then if I press save and page fails to validate these <select>s return to their original state. I already have it fixed, by keeping data in session and if it has certain key, <select>s are filled with correct data.
Why would I need automatically generated key? Well multi-tab working. If user would try to add 2+ new records to database at the same time (which is extreme, but possible), he needs to have that data kept under different keys so app can find desired stuff.
I could as well make client side validation, but... nope, just nope, too much work.
As for code, anything useful:
public ActionResult MethodUsedAfterPageLoad
{
...
Guid stronyGuid = Guid.NewGuid();
ViewData["strony"] = stronyGuid.ToString();
...
}
This way every refresh creates new Guid, but Guid is used as SessionKey!
If I do it following way:
public Class ControllerClass
{
private Guid stronyGuid;
...
}
This will reset variable, that's bad. Using static keyword is bad idea.
We have two forms so far, and need to switch from window1 in from1 (which is login screen) to windowX in formX using button (trigger code below):
begin
show_window('windowX');
go_block('some_block_in_formX');
end;
This gives error FRM-41052: Cannot find Window: invalid ID
So question is, should I add formX into show_window parameter in certain way or is there another approach? Thank you.
Please note, that forms are in different files.
that forms are in different files.
If the forms are different files, you need to call the other form using open form/call form/newform - whatever suits your needs.
show_window/go_block sequence can be used only when you're moving to different windows/blocks of the same form - and the error message
error FRM-41052: Cannot find Window: invalid ID
is complaining that it can't go to that Window because it's in a different form.
Each form effectively has a private namespace for all its windows, blocks, items, etc - and your code always runs within the context of a single form.
To solve this, you'll need a form parameter, plus some code in the other form, e.g.:
in formX, add a parameter ACTION
in form1, pass the value 'XYZ' to ACTION
in formX, in the WHEN-NEW-FORM-INSTANCE trigger, check if :PARAMETER.ACTION = 'XYZ', and if so, do your show_window and go_block. Copy the same code to your WHEN-WINDOW-ACTIVATED trigger.
Of course, you'll need to think about the name of the parameter (e.g. ACTION) and value ('XYZ') that will make sense to people maintaining your forms in the future.