Expand my Community achievements bar.

SOLVED

How do I setFocus on a field

Avatar

Former Community Member

When the user clicks a "new" button, our dynamic xds form creates a new row for them to enter data on.  By default the first field (after a button) gets focus.  What we would like to do is have the third field get the focus.

I'm assuming that in the "new" button I would do a setFocus on something.  But as a newbie, I wouldn't put money on that.

I think what is missing is the index of the row.  W/O that, it looks like this:

xfa.host.setFocus(data.sfPage.sfParent.sfTableRow.phone)

TIA,

Jerry

1 Accepted Solution

Avatar

Correct answer by
Level 6

This is on the right track.  A few things:

You will only want to use addInstance when the user is adding a new row.  This will cause a new row to appear on the form.  The newly added row is returned to you so you can reference the objects in it to, say, initialize some values.

Your error check will occur later, probably when a submit button is pressed so that you can validate the data.  At that point all of the rows will be added already, and you don't want to use addInstance any more or you'll just get new rows.  Instead, this is the time that you'll have to loop the rows (more about that later).

When you want to indicate an error on a row, setting the focus is not the best way.  You can only set the focus on one object, so if you have more than one row with an error it will only indicate one error.  Your current script will only indicate the last one found. Better to use a color highlight from the getgo; it's not any more complicated.

If all you want to do is make sure that a field is filled in, make it mandatory; the submit process will not proceed unless all mandatory fields are filled in.  If you want to do more advanced error checking on your data, you can use scripting.

There are numerous posts in the forum about how to handle validations before a submit.  A simple method is to place both a hidden submit button on the form, and a second regular button (visible) labeled Submit that does not really do a submit.  In the second button's click event you put the validation script.  If the script finds no errors then the script will execute a click on the hidden submit button which will submit the form.  Otherwise the script will highlight the errors and terminate; no submit will take place.

Here's an update to your script.  I don't know the full structure of your form so I'm guessing a little at the proper heirarchy, and you'll need to fill in the proper names for the values that are in italics. This script should reside in the click event for the "dummy" submit button.

// Get how many row instances we have

var nRows = tablename._sfTableRow.count;

var curRow = null;

var valid = true;

// Loop through all rows

for ( var i = 0; i < nRows; i++)

     {

     // Get the next row instance

     curRow = tablename.resolveNode("sfTableRow[" + i + "]");

     // Checks go here:

     if ( curRow.phone.rawValue == "" )

          {

          // Make border red and indicate that there is an error

          curRow.phone.border.edge.color.value="255,0,0";

          valid = false;

          }

     }

     // Only submit form if all fields are valid

     if ( valid )

          submitbutton.execEvent('click');

     else

          xfa.host.msgBox ("Please fill in all fields in red before submitting the form");

View solution in original post

7 Replies

Avatar

Former Community Member

Take a look at the attached. It allows you to pick the row and column, as depicted below.

p1.png

Steve

Avatar

Former Community Member

Thanks for the info.

In my case, we have a dynamic form so I don't know the row name.  I tried to get the current instance id with this:

data.sfPage.sfParent.sfButtonHolder.AddSubformButton1::click - (JavaScript, client)
    // add a new row
     sfTableRow.instanceManager.addInstance();
    // enforce focus on a field
    var row_ = 0;
    var here = "data.sfPage.sfParent.sfTableRow[" + row_ + "].phone";
    xfa.host.messageBox("Testing row is " + row_);
    xfa.host.setFocus(here);

where the user clicks an "add" button.  The new row appears as expected and as I'm forcing the row to the first one, that also works.  When I changed it to get an instance index, it still goes to "0":

    var row_ = sfTableRow.instanceIndex;

When I used this:

    var row_ = sfParent._sfTableRow.count;

The display message showed the proper number (first new record showed "2", next showed "3", etc).  But the "here" variable above didn't do a setFocus on the new (or any that I can see) record.  I think I need some kind of "Index" on the set or how would the system know what row to put the focus on.

Avatar

Former Community Member

I got it.  I had to decrement the row count.  It seems the row count is real (4 means 4 rows) while the index for the table is zero based (row 4 is index 3).

Thanks!

Avatar

Level 6

You don't need to search for the new instance, addInstance will return a reference to the new row (or null if the row was not added):

     var newRow = sfTableRow.instanceManager.addInstance();

     if (newRow != null)

          xfa.host.setFocus(newRow.phone);

Avatar

Former Community Member

So we create an alias for the new row?  This looks very interesting.  I expect that we will have to loop through all the records to look for missing/bad data.  If there is none, the data will go to a database.  If there is, it sure would be nice to position the cursor on the row/field that has the error.  And perhaps highlight it in red, but that's for the next time.

I would expect the code to look like this:

var nRows = sfParent._sfTableRow.count;

for (i = 0; i < nRows; i++)

{

  var curRow = sfTableRow.instanceManager.addInstance();

  if (curRow.phone == null)

     {

      xfa.host.setFocus(curRow.phone);

     xfa.host.messageBox("some warning");

     i = nRows;

     }

  else other tests{}

  else update database{}

}

That's just off the top of my head and could be buggy as all get out.  Does it look like it is close?

Avatar

Correct answer by
Level 6

This is on the right track.  A few things:

You will only want to use addInstance when the user is adding a new row.  This will cause a new row to appear on the form.  The newly added row is returned to you so you can reference the objects in it to, say, initialize some values.

Your error check will occur later, probably when a submit button is pressed so that you can validate the data.  At that point all of the rows will be added already, and you don't want to use addInstance any more or you'll just get new rows.  Instead, this is the time that you'll have to loop the rows (more about that later).

When you want to indicate an error on a row, setting the focus is not the best way.  You can only set the focus on one object, so if you have more than one row with an error it will only indicate one error.  Your current script will only indicate the last one found. Better to use a color highlight from the getgo; it's not any more complicated.

If all you want to do is make sure that a field is filled in, make it mandatory; the submit process will not proceed unless all mandatory fields are filled in.  If you want to do more advanced error checking on your data, you can use scripting.

There are numerous posts in the forum about how to handle validations before a submit.  A simple method is to place both a hidden submit button on the form, and a second regular button (visible) labeled Submit that does not really do a submit.  In the second button's click event you put the validation script.  If the script finds no errors then the script will execute a click on the hidden submit button which will submit the form.  Otherwise the script will highlight the errors and terminate; no submit will take place.

Here's an update to your script.  I don't know the full structure of your form so I'm guessing a little at the proper heirarchy, and you'll need to fill in the proper names for the values that are in italics. This script should reside in the click event for the "dummy" submit button.

// Get how many row instances we have

var nRows = tablename._sfTableRow.count;

var curRow = null;

var valid = true;

// Loop through all rows

for ( var i = 0; i < nRows; i++)

     {

     // Get the next row instance

     curRow = tablename.resolveNode("sfTableRow[" + i + "]");

     // Checks go here:

     if ( curRow.phone.rawValue == "" )

          {

          // Make border red and indicate that there is an error

          curRow.phone.border.edge.color.value="255,0,0";

          valid = false;

          }

     }

     // Only submit form if all fields are valid

     if ( valid )

          submitbutton.execEvent('click');

     else

          xfa.host.msgBox ("Please fill in all fields in red before submitting the form");

Avatar

Former Community Member

Thank you.  That is exactly what I was going for.