Expand my Community achievements bar.

Populate drop-downs from free text fields.

Avatar

Former Community Member

Hi all,

I have a problem which I can't quite get my head around.

Currently I have a flowed form, and among others, a free text field named 'sectors'. Attached to this field are some + and - buttons which use instance manager to add or remove more 'sectors' rows.

Once all the sectors have been added, I would like users to then be able to be able to select from drop-down lists elsewhere in the form that are populated from the 'sectors' items.

Im thinking that I need to add another button to the 'sectors' row, which might add the item to the required drop-down, but im not really sure how to do this as my JS really isn't that great!

Any help or suggestion would be greatly appreciated.

Cheers,

Lachlan.

8 Replies

Avatar

Level 10

Hi,

The best event to populate a dropdown is its preOpen event. You can use this to look back at the sectors and to add the items. There is an example here: http://assure.ly/jcTahK.

Also because you want to reference an object in a repeating row, you will need to resolve the nodes. There is an example here that shows the benefits of xfa.resolveNodes, which resolves the rows in one hit: http://assure.ly/kUP02y.

So if the repeating object is "Sectors" and the textfield in the repeating row is "sector", the following should get you close:

// First clear the items from the list

this.rawValue = null;

this.clearItems();

// Build new items

var nRows = xfa.resolveNodes("Table1.Sectors[*].sector");

for (var i=0; i<nRows.length; i++) {

     this.additem(nRows.item(i).rawValue);

}

Hope that helps,

Niall

Avatar

Level 7

Hey Niall,

I do this preOpen event a lot using hidden tables storing data. That way all the dropdown items for all dropdowns are in one place, for maintenance/changes. I am usually using formCalc. It is a great approach--really the best way to handle dropdown boxes--and I highly recommend it and use it even when there is no dependencies on previous user selections. And when there are, you can set i in the loop to a different starting row and ending row, without having to change the loop. Or, a different column.

As you have stated, you must clear the dropdown each preOpe--no question about that.

this.clearItems();

However, I haven't ever set the dropdown to null first --what are the risks in not doing that?

this.rawValue = null; 

I want to start doing that and maybe go back and add that to my existing scripts, if there is some risk.

Cheers,

Stephen

Avatar

Level 10

Hi Stephen,

The reason I would clear the previous selection of the dropdown is that if the associated data changes (in this case the Sector), then the selected value may now be invalid.

I just think using both clearItems() and null is safer.

Niall

Avatar

Level 7

Thanks Niall,

I always use clearItems()

These preOpen scripts must always use clearItems()

No question about it.

I thought clearItems() sets the value to null already and therefore, I was just wondering if the assignment to null was redundant/superfluous?  If there is a valid reason for that (setting to null) additional line in the script, I want to start adding it--maybe even go back and revise some previous work.

Thanks!

Stephen

Avatar

Level 10

Hi Stephen,

I would say that the this.rawValue=null; is necessary.

If in my example you comment out the null line. Then select the Fruit checkbox and Apple from the dropdown:

dd1.png

Now if the user goes back and deselects Fruit and instead selects Cars, when they open the dropdown the script clears the Fruit options and adds the Car options (everything okay there). However the value of the dropdown is still fruit_001, even though this is not an option in the list. If the user exists the dropdown without making a new selection, you could have a value displayed that does not relate to the correct choices:

dd2.png

So I would say that the this.rawValue=null; is not redundant at all.

In the null pattern for a dropdown: http://assure.ly/gcXx03, I actually null and clear the Relationship dropdown as soon as the user makes a selection in the Gender dropdown.

Maybe have a look and test before you go back on your existing forms.

Niall

Avatar

Level 7

Hi Niall,

You've given me something to think about.

In the forms I've been building, like your examples, the previous choice determines the dropdownBox available choices. OK, I approach it as you suggest when there are dependencies, like this, I add to the radio button change event:

///////////////////////////////////////////////////////////////////////////////////////////////

dropdownBox.clearItems()

dropdownBox = ""                 //I suppose I could use null here

xfa.form.execCalculate()

xfa.form.remerge()

///////////////////////////////////////////////////////////////////////////////////////////////

That forces the user to select from the dropdown box again and (in essence) resets the rest of the form that is dependant on the dropdownBox selection. My dropdownBox dependant fields, always have the test of if(hasValue(dropdownBox))then run this calculation script else $=0 endif. So all fields dependant on the dropdownBox selection (essentially) reset when the radio button changes, too.

So, I think I am OK on past forms, but like I said, you've given me something to think about.

Thanks!

Stephen

Message was edited by: kingphysh

Avatar

Former Community Member

You sir, are a life saver. Thanks!

It hasn't all been smooth sailing though. I have been stuffing around all day trying to get your code working. After reading many articles on resolveNodes, SOM expressions and populating drop-downs, I still couldn't get it to work.

I am now well versed in all these things, but it turns out the biggest issue was a lower 'i' on additem...

All good though I've learnt something, and what hasn't killed me has certainly made me stronger!

Thanks again,

Lachlan.

Avatar

Level 10

Hi Stephen,

Yes, the "" will work. I prefer null as giving an object no value, as opposed to a string of zero length. Both are very similar approaches and achieve the same ends, so I would agree that existing forms are okay.

Good luck,

Niall