Adding an existing form to a solutionModel created tabpanel

I have a form that is being created through the solutionModel. This form has also a tabpanel. On this tabpanel I’d like to attach an existing form (because this form has some beans on it that couldn’t be attached through the solutionModel).

I’ve tried to use the solutionModel.cloneForm() in order to attach the existing form to this solutionModel created tabpanel. Unfortunately, that doesn’t work (should it?).
Obviously the mixing of solutionModel and runTime code doesn’t work either (i.e. ‘elements.thenewlycreatedtabpanel.addTab()’).

Is there a way to get this done? Or is it impossible? I’ve understood that in the future there will be support for adding beans through the solutionModel (?), but is there a way to do this with the tools we have right now?

Well, I’m creating the habit to post the solution to my own questions on the forum… :D

It turns out that tha cloneForm() method works, you just have to use getForm() first and clone that. :idea:

Hi Kaptan,

please take a close look at the syntax and samples of the solutionModel. Basically all you need is in there.

Anyway, these should be the steps (of which you already have done the first 2 lines I guess):

var jsNewForm = solutionModel.newForm( name,  server_name|data_source,  [table_name],  style,  show_in_menu,  width,  height);
	var jsTabPanel = jsNewForm .newTabPanel(name, number x, number y, number width, number height);
	
	var jsFormWithBean = solutionModel.getForm(name);
	jsTabPanel.newTab(name, text,[b] jsFormWithBean[/b], [relation]);

The ‘magic’ is in getting an existing form through ‘solutionModel.getForm(name)’

Hope this helps!

EDIT: cloneForm shouldn’t be needed! .getForm works directly

Nice! I was using the extra line with cloneForm(). My first attempt was using the getForm() directly like you, but somehow that didn’t work right away (i think I called forms.formName instead of ‘formName’).
But now it’s working like a charm, thanks! :D

It turned out that using solutionModel.getForm() directly did create a problem. I was getting the ‘Stale form(s)’ error when changing element sizes on the parent form. Although I used history.removeForm() before sm.getForm(), it constantly gave the stale form error. I think it’s created because at a certain point you have the sm.getForm and a parent form with adjusted elements, both with the same formname. Using the solutionModel.cloneForm() and thus giving the cloned form a unique name, the stale form error disappears.

Maybe I haven’t grasped the complete concept of this, but I would say that using sm.cloneForm() prevents possible stale form errors when u create differences between the parent form and cloned form.

The ‘stale form’ error occurs when you make changes to a form which is still in cache.
When cloning a form, you have an uncached form which you can alter. For that reason you can make any alteration to your form UNTIL it is cached.
Downside to cloning is that this will be ‘another’ same form in cache, which is memory consuming.
Please be aware that Servoy only can have up to a certain number of forms in memory, which means cloning will slow down other parts of your solution as other forms have to be loaded into cache more often.

Anyway, solutions:

  1. When using Servoy 5 you can ‘commit’ your changes by using the form controller function .recreateUI(). You can make this happen even when your form is displayed.

  2. In order to alter forms by the solutionModel in Servoy 4, you have to delete your form from cache.
    This means: stop displaying a form (otherwise you can’t remove it, as Servoy still needs it)
    Then follow the example below:

var success = history.removeForm('myForm')
		//removes the named form from this session, please make sure you called history.remove() first
	if (success)
	{
		solutionModel.removeForm('myForm')
	}

Hope this helps!

note!: recreateUI() only works for UI stuff altered with the solutionModel. When adding for example form variables with the solutionModel. You definately have to go the second solution.

The strange thing is that I do not alter a form that is in the cache. (At least I think so). I am doing the exact thing you proposed, and alter the form after removing it. But still, when using the sM.getForm() directly I do get the stale form problem although I have altered the form before getting it and when it wasn’t in the cache. I have the feeling that when not cloning - and therefore not having a unique name for the getForm - the problem occurs. Anyway, I got it working with sM.cloneForm(). Thank you for thinking along with me!

mboegem:
note!: recreateUI() only works for UI stuff altered with the solutionModel. When adding for example form variables with the solutionModel. You definately have to go the second solution.

Mark, I’m working in Servoy 5 and alter forms with the solutionModel after removing them from view with history.removeForm().
Then use recreateUI().
But still get the message:
“Stale form(s) detected, form(s) where altered by the solution model without destroying them first
The form(s) that are stale (can also be a parent form if form inheritance is used) are: base_search[employeesearch,customersearch,base_search]”

Destroying the forms does not help because I cannot address the form’s methods and variables later, they’re not recognised.
Please, help.

Cheers,
Maria

maria:
But still get the message:
“Stale form(s) detected, form(s) where altered by the solution model without destroying them first
The form(s) that are stale (can also be a parent form if form inheritance is used) are: base_search[employeesearch,customersearch,base_search]”

This is a very close description of what is happening in the background.

Why this happens? I can’t say without knowing at least the code you use for these alterations. It might be even further down in your solution, in that case even the code isn’t enough to track down the problem.

But to be sure the stale form errors will not occur:

  1. do all your stuff at your startup method
  2. if not possible at startup make sure:
    a) hide the form
    b) remove form from history
    c) remove form
    d) do the solutionModel alterations

As for 2d > make sure you don’t mix up the SolutionModel code with get/set designtime properties like forms.myForm.elements.button_delete.enabled = false
Every reference to a form like forms.myForm will be enough to load this form into memory and stale forms will occur.

you do alter form “base_search” ?
and that form is a super class of others like “employeesearch,customersearch” ?

do you remove (or call recreateUI() ) on all 3 of them?

jcompagner:
you do alter form “base_search” ?
and that form is a super class of others like “employeesearch,customersearch” ?

do you remove (or call recreateUI() ) on all 3 of them?

Yes, Johan, I remove all of them, first children, then parent.
Another thing is that all of the forms in the solution have a common parent ‘base’ that contains common methods for all the forms.
Before I try to remove this form from history I do controller.show() on another form that does not have a parent.
However history.removeForm(‘base’) returns false after that.

mboegem:

maria:
But still get the message:
“Stale form(s) detected, form(s) where altered by the solution model without destroying them first
The form(s) that are stale (can also be a parent form if form inheritance is used) are: base_search[employeesearch,customersearch,base_search]”

This is a very close description of what is happening in the background.

Why this happens? I can’t say without knowing at least the code you use for these alterations. It might be even further down in your solution, in that case even the code isn’t enough to track down the problem.

But to be sure the stale form errors will not occur:

  1. do all your stuff at your startup method
  2. if not possible at startup make sure:
    a) hide the form
    b) remove form from history
    c) remove form
    d) do the solutionModel alterations

As for 2d > make sure you don’t mix up the SolutionModel code with get/set designtime properties like forms.myForm.elements.button_delete.enabled = false
Every reference to a form like forms.myForm will be enough to load this form into memory and stale forms will occur.

Marc, I don’t exactly understand how I can modify a form that is removed from solutionModel.
That is, after I do history.removeForm() and solutionModel.removeForm(), the form isn’t found by the solutionModel.getForm() any more.
2d means removing the form from solutionModel, doesn’t it?

There is one more interesting thing.
If I first remove the child from both history and solutionModel and then I remove the parent the same way, then I still can access the parent through solutionModel.getForm().
If I remove forms in the other order, first parent, then child, then I’m unable to access the parent.

Why does it happen?

P.S. After removing the forms and making changes I try controller.recreateUI() on both of them but it only works on the parent. Why so?

Ok, I got it.

The parent form that is being altered has multiple children and all of them need to be removed from history each time the changes are made.
As I was making changes to both child and parent, I thought I should only remove that child and the parent, the error came up because of that.

Thank you everyone contributing to the discussion.
There is so much going on behind the scenes that we don’t know and there’s really no other way to find out except from your kind suggestions :D

By the way, is there a way to find all extended forms for a parent form except looping through all forms in the solution and checking each of them?

Cheers,
Maria

i think the question is more why do you alter a base form that is used all over the place constantly at runtime when all the child’s could already be displayed?

but there is no other way to search for it through all the forms if it is a parent form. (and this has to be done recursively because of base->inbetween->child and you alter base)

Johan, in my scenario I have to add additional search criteria on the search screen which is extended from a parent form for each module (employees, customers, product search, etc).
The search criteria tab was in the header and the search results list tab was in the body.
Thus when I added a search criteria form I had to resize the header, and I can only resize the header of the parent, not child.
That’s where the problem was coming from.

I reviewed the form elements and removed the header now, don’t know why it was there.
Thanks for pointing that out, great relief.
The discussion was still very educational.