When the user goes to a specific form I want to add a couple of buttons to the default navigation framework button bar (svy_nav_fr_buttonbar_browser), I got an example from sanneke on how to do this, using myfom_onPreShow(). When the user goes to another form i need to remove those buttons again. So i thought I could use the myform.onHide() event to remove the buttons. This seems to work the first time the user enters and leaves myform, however when the user opens myform for the second time it first calls the myform_onPreShow() event (so the buttons are created) and right after that it calls myform.onHide() !! so the buttons are removed again.
function svy_nav_showForm(_form, _program, _showAll) {
...
//run onPreShow-method of program when available
if (globals[_program + '_onPreShow']) {
var _methodReturn = globals[_program + '_onPreShow']()
if (_methodReturn == -1) {
return -1;
}
}
//determine the template
var _template = globals.nav.getTemplate()
var _templateForm = forms[_template];
var _dividerHeight = _progObj.divider_height
globals.nav_base_form_name = _progObj.base_form_name
// empty related text
globals.nav.related_text = globals.nav.related_form = ''
// set view 1 with the form
forms[globals.nav.browser_form].elements.form_view_01.removeAllTabs()
globals.nav.form_view_01 = _form
...
This is a part of the code of svy_nav_showForm(_form, _program, _showAll) here you can see that onPreShow is called and as soon as the code comes to forms[globals.nav.browser_form].elements.form_view_01.removeAllTabs() it calls myform.onHide()
Am I doing something wrong in using onHide for this?
Also is there some documentation on the order in which form events get called within the framework?
if: forms[globals.nav.browser_form].elements.form_view_01.removeAllTabs() triggers the onHide, there’s 2 possibilities in my opinion:
one of the tabs of tabpanel ‘form_view_01’ already contained the form you want to navigate to. Though, when you end up in the situation where the requested form is shown, this situation is unlikely.
there’s something wrong in the globals.onHide() method. If this method is using a global variable in which the current form name is stored and which is calling the onHide method of this specific form, you might want to check the content of this variable as this could be set with the new form name in an early stage(maybe too early)
All this happens in svy_nav_navigation/globals.js.
First the myform_onPreShow is called, which creates my extra buttons on svy_nav_fr_buttonbar_browser. Later on in that function at the line I indicated it (that function) calls the OnHide event of myform (I dont call the onHide!). This happens only if my form had been shown at least 1 time before.
/**
* To show a form in the framework
*
* @author Sanneke Aleman
* @since 2005-11-24
* @param {String} _form the name of the form
* @param {String} [_program] name of the program
* @param {Boelean} {_showAll] Load all records
* @return none
*
* @properties={typeid:24,uuid:"c9f878b6-f664-4a42-b5cb-d60860396c05"}
*/
function svy_nav_showForm(_form, _program, _showAll) {
if (_showAll == undefined) _showAll = true;
//update the record history for the last program
globals.svy_nav_history_update_record()
if (_program == undefined) {
_program = globals.nav_program_name;
} else {
globals.nav_program_name = _program;
}
var _progObj = globals.nav.program[_program]
//if form doesn't exist create it, it can happen that table views don't exist but are created dynamicly
if (!forms[_form]) {
globals.svy_nav_createDefaultTableView(_program, _form)
forms[_form].controller.loadRecords(_progObj.foundset)
}
if (globals.nav.lastProgram) {
//save splitter last program shown
if (forms[globals.nav.template_types[globals.nav.lastView]].hasSplitter() && application.getApplicationType() != 5) {
globals.svy_utl_setUserProperty('Divider_' + globals.nav.lastProgram + '.' + globals.nav.lastView, forms[globals.nav.template_types[globals.nav.lastView]].elements.tab_split.dividerLocation);
}
}
globals.nav.lastProgram = _program
globals.nav.lastView = _progObj.view
//run onPreShow-method of program when available
if (globals[_program + '_onPreShow']) {
var _methodReturn = globals[_program + '_onPreShow']()
if (_methodReturn == -1) {
return -1;
}
}
//determine the template
var _template = globals.nav.getTemplate()
var _templateForm = forms[_template];
var _dividerHeight = _progObj.divider_height
globals.nav_base_form_name = _progObj.base_form_name
// empty related text
globals.nav.related_text = globals.nav.related_form = ''
// set view 1 with the form
forms[globals.nav.browser_form].elements.form_view_01.removeAllTabs()
globals.nav.form_view_01 = _form
// setMenuTree
if (!globals.svy_utl_compareArrays(forms.svy_nav_fr_tree.elements.dbtreeview.selectionPath, _progObj.path)) {
globals.nav.setMenuTree = 1
forms.svy_nav_fr_tree.elements.dbtreeview.selectionPath = _progObj.path
}
// set the foundset of the form, if a form doesn't have a table you don't have to load a foundset
if (_showAll && _progObj.table_name) {
if (_progObj.foundset) {
forms.svy_nav_base.dc_sort(globals.svy_nav_form_name, globals.nav_program_name, true);
_progObj.foundset.loadAllRecords()
forms[_form].controller.loadRecords(_progObj.foundset)
} else {
_progObj.foundset = databaseManager.getFoundSet(forms[_form].controller.getServerName(), forms[_form].controller.getTableName())
forms.svy_nav_base.dc_sort(globals.svy_nav_form_name, globals.nav_program_name, true);
// set filters
for (var j = 0; j < _progObj.filter.length; j++) {
var _value = globals.nav.program[_program].filter[j].filter_value
//global value is used
if (utils.stringPatternCount(_value, 'globals.')) {
_value = eval(_value)
}
_progObj.foundset.addFoundSetFilterParam(_progObj.filter[j].filter_field_name, _progObj.filter[j].filter_operator, _value)
}
_progObj.foundset.loadAllRecords()
forms[_form].controller.loadRecords(_progObj.foundset)
}
}
forms[globals.nav.browser_form].elements.form_view_01.addTab(forms[_form])
// sync the foundset, if there is a table
if (_progObj.table_name) {
var _index = forms[_form].foundset.getSelectedIndex()
for (var i = 0; i < _progObj.form.length; i++) {
if (forms[_progObj.form[i][2]]) {
forms[_progObj.form[i][2]].controller.loadRecords(forms[_form].foundset)
forms[_progObj.form[i][2]].controller.setSelectedIndex(_index)
}
}
forms[globals.nav_program_name + '_tab'].controller.loadRecords(forms[_form].foundset)
forms[globals.nav_program_name + '_tab'].controller.setSelectedIndex(_index)
}
globals.svy_nav_form_name = _form
// set the buttons
globals.svy_nav_dc_setStatus(globals.nav.mode, _form)
//set image to show with template is selected
var _elementsButtonbar = forms.svy_nav_fr_buttonbar_browser.elements
_elementsButtonbar.template_selected0.visible = _elementsButtonbar.template_selected1.visible = _elementsButtonbar.template_selected2.visible = false
_elementsButtonbar['template_selected' + _progObj.view].visible = true
//set the tabs of the program
var _return = globals.svy_nav_setTabs(_template, _progObj)
forms.svy_nav_fr_main.elements.tab_split.setRightForm(forms[_template], null)
// set the splitter
if (forms[_template].hasSplitter()) {
if (_progObj.divider_locked) forms[_template].elements.tab_split.dividerSize = 0
else forms[_template].elements.tab_split.dividerSize = 1
}
//Adjust layout based on divider height settings in configuration when using a template that has a splitter
if (_dividerHeight && _templateForm.hasSplitter()) {
_templateForm.elements.tab_split.dividerLocation = _dividerHeight;
}
// write form to history stack
globals.svy_nav_history_update(_form);
return _return;
}
jdbruijn:
So you are saying the error is in the servoy navigation framework?
Or am I wrong in using OnHide to achive my goal?
i dont know, it is quite complex to just know what happens with the description here on the forum.
Why would it be a bug in a navigation framework?
If you replace a tab panel with something else, then something will get an onhide.
So i dont know exactly what does trigger the onhide i am just saying is that myform that you show inside that splitpane? And do you replace that with that setRightForm call??
Because if you do then it very logical that onHide is called.
No problem john, I’ll try to explain in more detail.
I have created several forms in the navigation framework. One of these forms has to have extra buttons in de default button bar of the framework (svy_nav_fr_buttonbar_browser).
These buttons are created in the onPreShow event of that particular form (myform). When navigation away from this form to any other form these buttons have to be removed again, that is what I’m trying to do in the onHide event of myform.
When i run the solution and open myform for the first time it is working correctly: the buttons are created. Next I open any other form and the buttons are removed.
However if I now open myform again, then the buttons are not shown. Debugging showed me that they are first created (myform_onPreShow is called) and they are imediatly after that removed again because myform.onHide is also called.
I have not modified the code for the function svy_nav_showForm in anyway, so that is why I was wondering if there is a bug in that code or if I was wrong in trying to use onHide to remove the buttons.
As Johan already replied, there’s not much to see in the code you posted.
This doens’t solve your issue though…
I’d suggest you run the solution with a breakpoint set in the onHide method that takes care of removing the elements.
While navigating your solution, the execution will stop at the breakpoint and you’ll see the debug perspective opening.
In upperleft corner of this perspective you’ll see the history of methods which were executed prior to your breakpoint.
If you click back in this history, you’ll even see a highlighted line within a certain method, indicating the step triggering the next method.
This way you can see which step, which arguments are involved at this behaviour.
When i put a break point at the first line of my onHide event this is the call stack:
onHide
svy_nav_showForm
showProgram
The line in svy_nav_showForm is where I indicated earlier: forms.svy_nav_fr_main.elements.tab_split.setRightForm(forms[_template], null)
_template references the svy_nav_fr_template3 form.
showProgram is called when the user presses a button in our menu bar to the right it looks like this:
/**
*
* @properties={typeid:24,uuid:"5143B5D2-A0A4-4198-A731-F94EA281CB71"}
*/
function showProgram(_event, _program)
{
if(globals.nav.mode != 'browse') return; // no navigation in find and edit
if(!globals.nav.program[_program] || globals.nav.program[_program] == undefined) return
globals.nav.history = new Object()
var _template = globals.nav.template_types[globals.nav.program[_program].view]
var _form = globals.nav.program[_program].form[forms[_template].has1()][2]
// show the program
var _return = globals.svy_nav_showForm(_form, _program);
// sort the tables
if(_return == -1)
{
return
}
if(_return[0])// only if there are tabs
{
forms.svy_nav_base.dc_sort( _return[0], _return[1]);
}
}
ok so does svy_nav_fr_template3 replace the for myform? of that onhide method??
where is that myform located on the screen?
I’m not sure what is supposed to happen in svy_nav_showForm, and i dont know what that form template3 is supposed to do.
I’ve added a screen shot of my solution:
this is myform
the extra buttons i added
button to show my form
one of the buttons to show another form
And what is your stack then 2nd time when onHide is being called?
Marc the stack i gave you was when I switch back to myform for the second time (so when onHide is called for myform when i dont expect it.)
Maybe I should ask it in another way; could one of you tell me what the order of the (form-)events is when i switch forms? I cannot find any documentation on this. Maybe I should no try to do it in this way but use a completely different approach.
this is to hard to understand by a few screenshots.
Please contact support so that they can get you up to speed with the framework and the way servoy works.