Unable to get property 'appendChild' of undefined or null reference error on listbox. Here is the code.
function FORM_OnAfterDataInit() { var strPDL = portalWnd.oUserProfile.getAttribute("productline"); var s = "?PROD="+strPDL; s += "&FILE=EMPLOYEE&INDEX=EMPSET1&KEY=10&SELECT=SEC-LVL=2"; s += "&FIELD=EMPLOYEE;LAST-NAME;FIRST-NAME"; s += "&OUT=XML&MAX=200"; var sReturn = portalWnd.httpRequest(portalWnd.DMEPath + s) var vObjDMEXML = new portalWnd.DataStorage(sReturn); var vRecord = vObjDMEXML.document.getElementsByTagName("RECORD"); // //Variables defined to fill listbox // var Level1List = document.getElementById("VALUES_l27"); var ListVal; ListVal = document.createElement("span"); for (var ix=0; ix < vRecord.length - 1 ; ix++) { var vCols = vRecord[ix].getElementsByTagName("COL"); var str = vCols[0].firstChild.data; var str1 = vCols[1].firstChild.data; var str2 = vCols[2].firstChild.data; var str3 = str1 + ' ' + str2; alert('str ' + str); alert('str1 ' + str1); alert('str2 ' + str2); alert('str3 ' + str3); ListVal.setAttribute("tran",str); ListVal.setAttribute("text",str1); ListVal.setAttribute("disp",str3); alert('Maybe disp?'); Level1List.appendChild(ListVal); } }
Bill,
Are you using Infor version10.x? Infor changed the way you access list boxes. You've already discovered you have to remove "values" (you still need the underscore). Instead of creating a span and adding it to the listbox you just use a new function. Change your code to:
for (var ix=0; ix < vRecord.length - 1 ; ix++) { var vCols = vRecord[ix].getElementsByTagName("COL"); var str = vCols[0].firstChild.data; var str1 = vCols[1].firstChild.data; var str2 = vCols[2].firstChild.data; var str3 = str1 + ' ' + str2; lawformAddListboxOption('_l27, str1,str3);
}
It is documented but not overtly. In Design Studio, go into Tools --> Objects Viewer and expand Forms. Click on Form Functions and you'll see it there along with a function to remove an item from a listbox.
By the way, I left off a quote in my initial answer but you must have caught it. It should be lawformAddListboxOption('_l27', str1,str3);
If you want to select an item in the dropdown list you use setFormValue. Here is an example of populating a list box and selecting one of the options:
//Add 3 items to a dropdown list named of 'select36' with a field number of '_l680' lawformAddListboxOption('_l680', 'OR','OREGON'); lawformAddListboxOption('_l680', 'WA','WASHINGTON'); lawformAddListboxOption('_l680', 'CA','CALIFORNIA');
//Select the second item in the list. lawForm.setFormValue('select36','WA');
Setting the form value doesn't actually select the item in the dropdown however. If you were to get the selectedIndex attribute for the drop down list after setting the form value it would be -1 rather than "1" as you would expect.
Unfortunately you can't do much more (or if you can I don't know how). For example, standard javascript functions to get the text for WA (which is Washington) don't work. I'm not sure how Infor is rendering the drop down list but I have a feeling it's not a normal drop down list otherwise we'd be able to access the "text" attribute which would give you "Washington".
The way I got around this was to load my dropdown list items into an array. Then I loaded the dropdown list from the array. Then when someone selected an item from the dropdown list I would get the corresponding value from the array and place it into a label field.
Hopefully this helps.
I've attached a javascript file that I include in AP10.1. The file contains functions to load a dropdown list of states. Our users wanted a dropdown list when adding vendors rather than a freeform text box so this is what I came up with. Note that I had to rename the file with a "txt" extension because I can't upload a .js file. If you want to use it you'll need to rename it back to a .js file once you download it.
In your FORM_OnInit() function you would call two functions:
// Load the global gStateProvinceObject with all the US States and Canadian Provinces. loadStateProvinceArray();
// Load the State or Province drop down with the values in gStateProvinceObject. Note that we // can't assign the database field 'VDR-STATE' to the listbox. If we do, we can't populate it so // we use our own listbox and then set the form value in the values_onblur event for the listbox. loadStateProvinceListBox('_l623',gStateProvinceObject);
Here is the code I added to VALUES_OnBlur:
// Get the State or Province value that the user selected for this vendor. if (id == "select35") { var stateCode = lawForm.getFormValue("select35");
// Set the value of the hidden state field to the value that was selected so // when we do a change, the new value gets updated in the database. lawForm.setFormValue('hidden78',stateCode);
// Set the value of the label next to the state listbox to the name of the state. lawForm.setFormValue("text85",getNameFromAbbreviation(stateCode,gStateProvinceObject)); }
And then finally, here is the code I added to the FORM_OnAfterTransaction function to select the state based on the state code for this vendor:
//Select the state in the state list box. lawForm.setFormValue(gStateOrProv_sel,lawForm.getDataValue("VDR-STATE"));
// Get the State or Province name for this vendor and put it in the textbox next to the state. lawForm.setFormValue("text85",getNameFromAbbreviation(lawForm.getDataValue("VDR-STATE"),gStateProvinceObject));
When you do any transaction (inquiry, next, prev, change, etc) the FORM_OnAfterTransaction function will be invoked when the data is returned from the COBOL program. At that point you can obtain the value of the field you want by using lawForm.getDataValue("your data field name"); Then you put that value into the form field using lawForm.setFormValue("your form field");. In the example below I am getting the value of the state code (VDR-STATE) that was returned by my inquiry and placing it in the drop down list (select35). Give that a shot and see if it works.
Put this in the FORM_OnAfterTransaction function:
//Select the state in the state list box. lawForm.setFormValue("select35",lawForm.getDataValue("VDR-STATE"));
Your code looks correct. Your dropdown list isn't in a detail area control is it? If so you need to specify the index of the line with the control. That doesn't sound like it's the case though.
In order to set the value of select1, the value has to be one of the options that are already in the select1 list. For example, if your select1 contains 'CA','OR' and 'WA', you can only set it to one of those values. You can't set it to 'NV' for example. If you are populating the list in the form_onInit function it should already have all your values. Can you confirm that the value in the lev6 variable is already in the list box?
Is Text2 where you are displaying the description for the value selected in the list box? If so, rather than making it hidden, just make it an output only field by selecting the field in Design Studio; selecting (Custom) in the properties window and checking the Output Only check box.
Also, you appear to be about 99% there so I wouldn't recommend re-engineering your solution but I did figure out how to get the display value of the selected item in a list box. I put the following in my VALUES_OnBlur function.
if (id == "select2") { // This is your list box
var mylistbox = lawForm.getElement("_l623"); // This gets a reference to your list box. Make sure you change the ID (_l623') to your list box ID.
for (var i=1; i < mylistbox.childNodes.length; i++) { // This will loop through all the items in the list box. if (mylistbox.childNodes.selected == true) { // This tests to see if the item is selected. var myDisplayValue = mylistbox.childNodes.attributes['disp'].nodeValue; // This gets the display value of the selected item. break; //This breaks out of the for loop. No need to continue checking items after you've found your selected item. } }
When you leave this loop, myDisplayValue will contain the display value of the item that was selected. If you use this method you don't need to mess with arrays; you can just load your list box and then use this method to get the display value. I also placed the code in my FORM_OnAfterTransaction function (removing the if (id == "select2") code ) to display the name of the state from the value in VDR-STATE.
Oops, sorry, I left out the index. Use this one:
Apparently code in brackets gets removed when you post. So for these two lines:
if (mylistbox.childNodes.selected == true) { // This tests to see if the item is selected. var myDisplayValue = mylistbox.childNodes.attributes['disp'].nodeValue; // This gets the display value of the selected item.
after the word "childNodes" and before the period add a left bracket, an "i" and a right bracket.
As for that hidden field, I understand now. This is what my XML source looks like:
fld al="left" blankzero="1" col="13" ed="upper" height="1" id="hidden78" label="State or Province:" mxsz="2" nbr="_f52" nm="VDR-STATE" par="TF0-0" row="11" seltype="" sz="2" tp="Hidden"
Make sure the nbr and nm fields contain the proper values for the field you are updating. Not sure if the field name is important but you might try changing it to hiddenxx (something unique).