Hello All,
I have a form that needs a global array. Several functions use the array and I have worked out how to keep the array in sync between them when the user completes various actions. The difficulty I have run into is initializing the array. For a global variable or array usually I would do this:
{! GLOBAL gArrayString = array ()}
This works great if the user does not put the visit on hold. However, if the user puts the visit on hold, as you would imagine, the array is reset. I need to have this value be persistent even if the user puts the visit on hold. Does anyone have any suggestions for setting up variables/arrays that can be used between functions and also keep their value if put on hold?
Thanks,
Brad
Have you considered using a conditional statement? something like:
{
!if gArrayString == "" then
gArrayString = array ()
else
endif
}
If I'm not mistaken, global variables lose their persistence when the form is put on hold, so you might consider writing the values of the array to a file that gets created in a location that is accessible by all the computers that might need access to it (e.g. network drive). The file name could contain the document ID of the encounter that initiated the document to ensure that it was unique and avoid conflicts if the encounter template was used by multiple people. I would probably store the array values in pipe/caret delimited format (|/^) if it is a two-dimensional array or caret delimited if one-dimensional. You could then have a function written in MEL to check for the existence of this file when the form loads and then parse the values into your array. You would obviously need to put these files in an area that was secure and could be cleaned out periodically (i.e. deleted).
Thank you for the suggestion. That is the crux of my problem. I can't get the array to persist through being put on hold. I tried dumping the contents of the array to a comma delimited string in a document variable so I could recreate it when I pull the visit off of hold, but I can't seem to keep that in sync.
Sounds like you are on the right track. I would think that dumping the contents of the array (comma delimited) into a hidden document variable would work. You could still use a conditional if/then/else that would fire when the form opened to load the values in the hidden document variable back into the array. You'll need to update the document variable every time a value gets added into the array so perhaps that is the issue. A watcher expression that calls a function to update the document variable should work as well. I suppose you could use an unused OBS term to store the values instead of a document variable. Watcher expressions seem to work more reliably when an OBS term is updated. For troubleshooting purposes, try putting a userok("function fired") in your code so you can verify that your update function is firing every time the document variable should get updated. I've used this strategy in the past with some success. It is often difficult to know when a function is getting fired when a watcher expression is involved.
So I tried to populate from a document variable. My issue is that the watcher function initializes randomly during the visit. This is my code:
{!
GLOBAL gHCCstring = array()
//check if anything has been clicked
if (document.HCCDISPLAYHIDE <> "") then
gHCCstring = getfield(document.HCCDISPLAYHIDE,",","")
else
""
endif
}
Looking at the code above this is how this should work: I setup the array. If visit was previously open and then put on hold, if there were values selected they will be in document.hccdisplayhide. So, I grab those and dump them into gHCCstring. If this is the first time the visit has been opened, or nothing was selected the array is blank which is what we need it to be.
This works great. The issue is hccdisplayhide gets values from a listbox. I can click two values and it is fine. Once I click on the third value the array initializes again and blanks everything out with the exception of the first value. I tried removing the '!' at the beginning of the function to only have it run once, but the array doesn't initialize at all that way.
I would prefer to not write this to another file but I'm starting to think that might be my only choice.
Brad
Global variable disappear on putting document on hold. If the variable needs to be initialized, then you need to create a variable that tracks if the form has been loaded and if not initialize the form. I do this by creating a document variable document.form_loaded. Create a function Initialize_Form(). In the Initialize_Form() routine set up the desired variables. You can't simply call this function on form load as there can be timing problems that preclude execution of the function. Thus, you need to create a brute force check on form initialization and execution. I do this in the translation of the document.form_loaded variable as follows: {if document.form_loaded<>"yes" then Initialize_Form() "" else "" endif}. Note the null quotes are important. The last line of Initialize_form routine is document.form_loaded="yes". Please contact me if you would like additional information.
I have created forms that deal with arrays that need to be saved. I read and write the arrays to a file, fields delimited by "^" and records delimited by "|". You need to monitor add, delete, modify changes. Colossal coding pain. Let me know if you would like to see an example of the process.
The problem appears to be related to the fact that you are initializing the array when the form loads but are also initializing it every single time the document.HCCDISPLAYHIDE variable changes. You can see when your watcher expression fires by putting a userok("My watcher expression fired. Contents of gHCCstring variable: " + gHCCstring) into your code. This will help you make sense of what is causing the expression to fire and display contents of your variable. You might put this expression both before and after the if statement to see what contents of the variable were before and after. Dr. Fitzgerald's approach should work for you as well.
Thank you both for the feedback. Sometimes you just need to bounce things off of others. I looked at the your suggestions and other options. I ended up rewriting the two functions that used the global array. I was able to rewrite one so that the array was no longer needed. Since it was no longer needed I was able to define the array as local in the function that did need it which fixed my sync issue. Thanks again for the help.
Brad