Wednesday, August 22, 2012

APEX Tabular Form: focus cursor on first element of new row

focus0I just got the question from a fellow developer, how to focus the cursor to the first input field of a newly added row using the ADD button in a standard APEX Tabular Form. Actually, I would expect APEX to do this automagically. But it doesn’t. To implement this behavior is actually really simple.

 

 

For this example I create a simple tabular form based on the demo_customers table:

focus1

This is what the form looks like when you click the “Add Row” button. As you can see, none of the input field has focus at this time. To focus the cursor on the first field of the new row (Cust First Name), I somehow have to change the behavior of the “Add Row” button. Let’s have a look at it’s definition:

focus2

The click-action of the button is actually a JavaScript call: addRow();. Naturally I want to keep this action, but after this, I want to start an additional action that should set the focus to the input field. To be able to have multiple actions performed when the button is clicked, I will change the Action definition to “Defined by Dynamic Action”:

focus3

Now I’m going to add a Dynamic Action to the “Add Row” button. First action will be the original JavaScript call to add the row, second action will be setting the focus. This is how the definition will look like after I added the actions:

focus4

Creating the Dynamic Action and the first True Action I will do with the Create Dynamic Action Wizard for the button:

focus5

focus6

focus7

focus8

Now I have implemented the original behavior.

Next I want to focus the cursor on the first text-field of the added row, once I click the button. I know there is a build-in Dynamic Action to set the focus on an element. I just need to know which element. Let’s have a look at the HTML code of the generated APEX page, especially the the text-field element we wish to target (I used the Chrome Developer Tool here):

focus9

As you can see, the name of this element is f02 and the id f02_0008. Because the ID can change depending on the number of rows displayed, I choose to work with the name attribute, which stays the same. The problem is, all “Cust First Name” fields do have the same name. Luckily jQuery offers a way to select the last element in an array of element with the same name and luckily, APEX Dynamic Actions support jQuery selector syntax. So here is, how I define the focus action for my “Add Row” button:

focus10

focus11

As you can see, I select all elements having the name attribute equal to f02 and :last allows me to select the last element of these. Here is a screenshot from the result (after clicking the “Add Row” button) with focus on the first text element of the last, newly added row:

focus12

Saturday, August 18, 2012

Running Standalone APEX Listener as Windows Service

Service
When working with APEX you certainly want to use the APEX Listener. It’s a great piece of software and Oracle is committed to extend its functionality (Oracle recently release the beta version of the new APEX Listener 2.0).
When installing the APEX Listener, you basically have two choices:
  • run APEX Listener “Standalone”
  • deploy the Listeners WAR file to one of the supported webservers
The problem (at least, my problem): when using the APEX Listener on my laptop/desktop with my local APEX instance, I do not want to set up a whole webserver, just to be able to develop APEX applications. So I,’m choosing the lightweight option: Standalone! But the annoying thing about the standalone installation is, that I have to start the APEX Listener from the command line each time I want it to be available. It just would be so much easier to just have it as a Windows service, stating during system boot.
Seems that an APEX developer from Poland, Andrzej Nowakowski, solved this problem for us and blogged about it, but the reason I probably never read his post is that he wrote the post in Polish. I followed the (Google Chrome) translated instructions, and after a little (just a little) struggle, I have my APEX Listener running as a Windows service.
So here is my post, mostly translating Andrzej’s instructions, in English.
Usually you would install/start the APEX Listener standalone mode by issuing the following statement, as documented in Oracle’s Installation Guide:
java -jar apex.war
This will create my Listener’s configuration files in the Windows path C:\Users\christian\AppData\Local\Temp\apex by default, using ${java.io.tmpdir}/<Mount-Point>/apex-config.xml. To avoid using the environment variables, which could be different when starting APEX Listener during system startup as a service, I’m going to let the Listener create its configuration files in a less user-dependent path using the listeners command line parameter –Dapex.home:
java -Dapex.home=C:\oracle\apex_listener.1.1.4.195.00.12\listener_conf -jar apex.war
C:\oracle\apex_listener.1.1.4.195.00.12 is the folder I installed/extracted the Listener software into. For the rest of the installation process, just follow the instructions in the installation guide. Now you should have a command line window open running the APEX Listener. Closing this window will shut down the listener.
To get rid of starting the Listener manually, we need to find a way to start the command as service. A little freeware program does the trick: NSSM - the Non-Sucking Service Manager. Starting NSSM, you just need to enter the <path>/command, its command line options and a name for the windows service. Make sure nssm.exe is installed somewhere where Windows can find it through the $PATH environment variable.
For my APEX Listener, I create a .bat file that I then call as service startup script, startlistener.bat, and put it into my Listener’s installation folder.
c:
cd \
cd C:\oracle\apex_listener.1.1.4.195.00.12
java -Dapex.home=C:\oracle\apex_listener.1.1.4.195.00.12\listener_conf -jar apex.war

Now all I have to do is starting a command window (in Administrator mode) and call
C:> nssm install
I enter my .bat file and give my service a name in the dialog window popping up:
nssm
Done:
taskmanager

themes4apex