Link to home
Start Free TrialLog in
Avatar of futureDBA
futureDBA

asked on

APEX: Update on Change on field while not loosing focus

This is a revisited question I had asked, i was set on the right direction but have not been able to figure out how to achieve the following, and at this point i give up and would like help or step by step instructions on how to figure this out


I have a tabular form with 2 columns, column 1 cannot be edited. column 2 is a text field. if i press tab i will go to the next row of that column which is another text field.

I want to be able to update that row everytime I press tab and at the same time move to the next row, if i edit that and press tab move to the next row etc.

I was able to call a process through a button using dynamic actions, the problem with this is that everytime i press tab and the row is updated. i loose focus and have to click the following rows text field to regain focus.
Avatar of gatorvip
gatorvip
Flag of United States of America image

Try adding this at the end of your DA

$('this').focus();

See the docs here:
http://api.jquery.com/focus/


You might also want to add JavaScript to the list of TAs for this question.
Avatar of futureDBA
futureDBA

ASKER

My dynamic action is called on a change event on a region

the action is Submit page which calls a butten (Submit) that processes a Multi Row Update on a tabular form

I am not sure what you mean by add "$('this').focus();" to the end of the DA.. where exactly?
Sorry - I assumed you were using JS. Do this:

Edit your DA
Click on Add True Action

add the following:
Action - Component/Set Focus
Fire When Event Result is True
Selection Type - Triggering Element (which in your case will be the region).

I think this is as clean as it can get without having to write code. If this doesn't do what you need, you will have to use JS.
i followed your example making the Set Focus action the first and last sequence, wouldnt work either way.

could you please help me with the JS method?
You don't want it to be the first sequence, you want it to be the sequence following the one where you call the PL/SQL process. I don't know why this doesn't work in your app, maybe upload a relevant sample app on apex.oracle.com and post the guest login credentials here?  I built a tabular form with two text fields, just as you described yours, and the DA method from my previous post worked fine. Do you happen to have calendar items or checkboxes, which could get the focus but you wouldn't necessarily see that?

I can't write the JS for you but the idea is something like this:
- the tabular form is relayed in HTML as arrays named fcc_rrrr where cc is the column index and rrrr is the row
- when you click inside one of the text fields, you can get its name and from there you can deduce the position
- in turn, this means you can code the "next" field to get focus should be
- finally, with the jquery focus() call you can set the focus on the field you want
i replicated what i have on apex.oracle.com

apex.oracle.com

Workspace: EETESTGATOR
Username: gatorvip
Password: gatorvip

I followed your rules, as of right now when i make a change to the field, it will update the field, but instead of moving to the next row after the update, i loose focus
the example doesn't match what you had in the OP. In particular:

I was able to call a process through a button using dynamic actions

I thought this meant you actually had a PL/SQL process which you then called in the DA. However, in the app I saw that you're actually doing a page submit, not calling a process. When you do the submit, you lose the page information so the previous focus information is no longer valid.
 
There's another JS solution that I started implementing for you on a new page (3). Prior to the page submit, grab the row information for the focused element (like rowid or field name). I did this via a JS function called processElement, which I added to the page JS header. I also added a call to this function from the Attributes property of the Quantity field.

What the javascript function does is generate a popup with the name of the triggering element. For example, if you change the Monster quantity from 5 to 10, then tab out of it, you will get a popup with the following text: f02_0004, which means it's column 2 and row 4.

Using the split() function, you can grab 0004 from the text above. Then you just convert it to a number (4), increment by 1 to get the next row (5), then turn it back into text (0005). So then your next focusable element becomes f02_0005. Save this value into an application item.

Finally, add apex.submit() or apex.submit('SUBMIT') to the JavaScript function in order to actually submit the page when you make a change to your field.

Now here is where it gets a bit tricky. You will need a separate page process that sets the next focusable element upon page load. You already have the element itself (saved in the application item) so you can just call document.getElementById with that name. The problem becomes cross-browser compatibility for the focus function. In theory,  document.getElementById(YOUR_APP_ITEM).focus() should work but I haven't tested it with all browsers.
is there any documentation out there geared towards finishing the solution you started to implement?

The truth is that it would to take me a couple of days/weeks to do the research and finishing this off on my own
particularly. the following confuses me

"Now here is where it gets a bit tricky. You will need a separate page process that sets the next focusable element upon page load. You already have the element itself (saved in the application item) so you can just call document.getElementById with that name. The problem becomes cross-browser compatibility for the focus function. In theory,  document.getElementById(YOUR_APP_ITEM).focus() should work but I haven't tested it with all browsers."
also, where on the page do i proceed with the split function?
ASKER CERTIFIED SOLUTION
Avatar of gatorvip
gatorvip
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Just for archiving purposes, the (unoptimized) javascript is as follows. To submit the page, uncomment the last line.

var htmldb_delete_message='"DELETE_CONFIRM_MSG"';

function processElement( pElement )
{
  // pElement has the form f02_0004
  var splitResult = (pElement.id).split("_");
  // the row is in the second element, i.e., 0004
  var currRow = parseInt( splitResult[1] );

  // how many rows does the tabular form have?
  var tabformNumRows = document.wwv_flow.f02.length;

  // get next row that will receive focus
  // have to be careful not to exceed the number of rows 
  var nextRow = currRow;
  if (currRow < tabformNumRows)
  {
    nextRow = currRow + 1;
  }

  // now that we know the next row, create the actual element that will receive focus after page submit
  // the prefix (f02) is still stored in splitResult[0]
  var nextElementID = splitResult[0] + "_"; 
  if ( nextRow < 10 ) 
    nextElementID = nextElementID + "000" + nextRow;
  else if ( nextRow < 100 )
    nextElementID = nextElementID + "00" + nextRow;

  // check the value of the current and next elements
  // alert( "current element = " + pElement.id + ", next element = " + nextElementID );

  // finally, set the value of the hidden page item
  // see docs here: http://docs.oracle.com/cd/E17556_01/doc/apirefs.40/e15519/javascript_api.htm
  $s( 'P3_NEXT_FOCUS_ELEMENT' , nextElementID  );
 
  // uncomment the following line to submit the page
  // apex.submit( 'SUBMIT' );
}

Open in new window

Truly appreciate your help, my experience is geared more towards oracle and some apex, i do not write java and this would have taken too much time for me to figure out, i think i can take it the end and figure out this last stretch