How to create elments in a loop

Questions and answers for designing and implementing forms in Servoy

How to create elments in a loop

Postby hareendra » Mon Aug 25, 2014 9:25 am

Hi,

I am trying to create a few elements in a loop, using the solution model. However I'm having a lot of difficulty naming the elements. Please see my code below.
Code: Select all
var jsform          = solutionModel.newForm(stmpForm, _dataSource, null, true, 510, 300);
   jsform.view       = JSForm.RECORD_VIEW;   
   jsform.styleName    = 'tmpstayle';      
   jsform.scrollbars   = SM_SCROLLBAR.HORIZONTAL_SCROLLBAR_NEVER;
   jsform.navigator   = SM_DEFAULTS.NONE;   
   var sFunctionName   = '';
   for (var index = 1; index <= dsDataset.getMaxRowIndex(); index++) {
      var row = dsDataset.getRowAsArray(index);         
      sFunctionName = row[2];      
      
      var jsButton = jsform.newButton(row[0], (2 + (index * 120)), 10, 110, 20, '');
      jsButton.onAction = jsform.newMethod('function  row[2]() { forms.frm_main.elements.tab_main.removeAllTabs();       forms.frm_main.elements.tab_main.addTab(form_name); }');
      jsButton.styleClass    = 'tab';
      jsButton.showClick   = false;         
   }
   elements.tab_main.addTab(sNavigationForm);   


The dataset contains a list of cloumns (label_name, form_name, function_name);
I am tring to set the value of function_name (row[2]) as the name of the function set to the onAction() method of the button. How do I set the function name (in the loop)? Because, the name has to be dynamic.
I get the following error: method argument not a jsmethod

I also need to create more than one button (in a loop). How do I name the jsButton in the loop? Because the name has to be dynamic.

Regards,
Hareendra
hareendra
 
Posts: 98
Joined: Wed Sep 17, 2008 11:41 am

Re: How to create elments in a loop

Postby ROCLASI » Mon Aug 25, 2014 10:12 am

Hi Hareendra,

Looking at your code I see 2 things:
1) you put a variable (row[2]) inside a string so it will be treated as a literal and not as a variable.

jsButton.onAction = jsform.newMethod( 'function row[2]() { forms.frm_main.elements.tab_main.removeAllTabs(); forms.frm_main.elements.tab_main.addTab(form_name); }' );

2) why do you create x amount of methods that in fact do the same thing. Just create one and assign it to all your methods.
Like this:
Code: Select all
var jsform          = solutionModel.newForm(stmpForm, _dataSource, null, true, 510, 300),
    jsFunction      = jsform.newMethod('function  myButtonFunction() { forms.frm_main.elements.tab_main.removeAllTabs();       forms.frm_main.elements.tab_main.addTab(form_name); }'),
    jsButton,
    row;

jsform.view = JSForm.RECORD_VIEW;   
jsform.styleName = 'tmpstayle';       
jsform.scrollbars = SM_SCROLLBAR.HORIZONTAL_SCROLLBAR_NEVER;
jsform.navigator = SM_DEFAULTS.NONE;   

for (var index = 1; index <= dsDataset.getMaxRowIndex(); index++) {
    row  = dsDataset.getRowAsArray(index);           
   
    jsButton = jsform.newButton(row[0], (2 + (index * 120)), 10, 110, 20, '');
    jsButton.onAction = jsFunction;
    jsButton.styleClass = 'tab';
    jsButton.showClick = false;
}
elements.tab_main.addTab(sNavigationForm);


As for creating unique button names. I tend to use the loop index to add to a generic name. Like myButton_1, myButton_2, etc.
This way you ensure you always have a unique name and if you use it on multiple elements in the loop they are also sort of grouped together by way of that index.
This is a technique I used heavily in the Gant module.

Hope this helps.
Robert Ivens
SAN Developer / Servoy Valued Professional / Servoy Certified Developer

ROCLASI Software Solutions / JBS Group, Partner
Mastodon: @roclasi
--
ServoyForge - Building Open Source Software.
PostgreSQL - The world's most advanced open source database.
User avatar
ROCLASI
Servoy Expert
 
Posts: 5438
Joined: Thu Oct 02, 2003 9:49 am
Location: Netherlands/Belgium

Re: How to create elments in a loop

Postby hareendra » Mon Aug 25, 2014 10:49 am

Hi Robert,

Thank you very much for your input.
Can you also show the syntax of adding the loop index to the button name?
I tried
Code: Select all
jsButton_[index]

However I get an error "Unexpected ["

Additionally I think the declaration of the JSMethod should be inside the loop. Otherwise "form_name" will always have the same value. Any ideas on how to accomplish that?
Regards,
Hareendra
hareendra
 
Posts: 98
Joined: Wed Sep 17, 2008 11:41 am

Re: How to create elments in a loop

Postby ROCLASI » Mon Aug 25, 2014 11:24 am

Hi Hareendra,

jsButton is in this case not an array you can't use that syntax.
Just add the index as a suffix to the button name like so:

Code: Select all
// add a suffix to the button name using the loop index
jsButton = jsform.newButton(row[0] + "_" + index, (2 + (index * 120)), 10, 110, 20, '');


As for the method code. In your original example you would also have always the same form_name in the code. So what should the method do exactly ?
Do you have any (meta) data in your dataset that can help the loop to determine what code it should generate?
Robert Ivens
SAN Developer / Servoy Valued Professional / Servoy Certified Developer

ROCLASI Software Solutions / JBS Group, Partner
Mastodon: @roclasi
--
ServoyForge - Building Open Source Software.
PostgreSQL - The world's most advanced open source database.
User avatar
ROCLASI
Servoy Expert
 
Posts: 5438
Joined: Thu Oct 02, 2003 9:49 am
Location: Netherlands/Belgium

Re: How to create elments in a loop

Postby hareendra » Mon Aug 25, 2014 11:37 am

Hi Robert,

The meta data is from a db table. So the dataset is based on a query. And it is that dataset that I am looping through.
For example,

col1(label_name) col2(form_name)
test1 frm_test1
test2 frm_test2
hareendra
 
Posts: 98
Joined: Wed Sep 17, 2008 11:41 am

Re: How to create elments in a loop

Postby ROCLASI » Mon Aug 25, 2014 12:20 pm

Hi Hareendra,

You can do this using the following code. It is however required that you sort the dataset by the form_name column though.

Code: Select all
var jsform = solutionModel.newForm(stmpForm, _dataSource, null, true, 510, 300),
    jsFunction,
    jsButton,
    row,
    sLastForm;

jsform.view = JSForm.RECORD_VIEW;   
jsform.styleName = 'tmpstayle';       
jsform.scrollbars = SM_SCROLLBAR.HORIZONTAL_SCROLLBAR_NEVER;
jsform.navigator = SM_DEFAULTS.NONE;   

// Make sure dsDataset is ordered by the form_name column
for (var index = 1; index <= dsDataset.getMaxRowIndex(); index++) {
    row  = dsDataset.getRowAsArray(index);           
   
    if ( sLastForm != row[1] ) {
        // Get the new method definition
        jsFunction = jsform.newMethod('function  myButtonFunction() { \
                                        forms.frm_main.elements.tab_main.removeAllTabs(); \
                                        forms.frm_main.elements.tab_main.addTab("' + row[0] +'"); \
                                        }');
        // remember which form we last processed
        sLastForm = row[1];
    }
    // add a suffix to the button name using the loop index
    jsButton = jsform.newButton(row[0] + " " + index, (2 + (index * 120)), 10, 110, 20, jsFunction);
    jsButton.styleClass = 'tab';
    jsButton.showClick = false;
}
elements.tab_main.addTab(sNavigationForm);


But this is kinda cumbersome. You could make your code more generic by encapsulating the addTab logic inside the frm_main form where it belongs. And simply calling a method on that form and pass the new form name to it like so:
Code: Select all
function addNewTab(sFormName) {
   elements.tab_main.removeAllTabs();
   elements.tab_main.addTab(sFormName);
}


Then your loop could look like this:
Code: Select all
var jsform = solutionModel.newForm(stmpForm, _dataSource, null, true, 510, 300),
    jsFunction = jsform.newMethod('function  myButtonFunction() { forms.frm_main.elements.addNewTab(controller.getName());}'),
    jsButton,
    row;

jsform.view = JSForm.RECORD_VIEW;   
jsform.styleName = 'tmpstayle';       
jsform.scrollbars = SM_SCROLLBAR.HORIZONTAL_SCROLLBAR_NEVER;
jsform.navigator = SM_DEFAULTS.NONE;   

// Make sure dsDataset is ordered by the form_name column
for (var index = 1; index <= dsDataset.getMaxRowIndex(); index++) {
    row  = dsDataset.getRowAsArray(index);           
   
    // add a suffix to the button label using the loop index
    jsButton = jsform.newButton(row[0] + " " + index, (2 + (index * 120)), 10, 110, 20, jsFunction);
    jsButton.styleClass = 'tab';
    jsButton.showClick = false;
}
elements.tab_main.addTab(sNavigationForm);


Hope this helps.
Robert Ivens
SAN Developer / Servoy Valued Professional / Servoy Certified Developer

ROCLASI Software Solutions / JBS Group, Partner
Mastodon: @roclasi
--
ServoyForge - Building Open Source Software.
PostgreSQL - The world's most advanced open source database.
User avatar
ROCLASI
Servoy Expert
 
Posts: 5438
Joined: Thu Oct 02, 2003 9:49 am
Location: Netherlands/Belgium

Re: How to create elments in a loop

Postby hareendra » Mon Aug 25, 2014 1:27 pm

Hi Robert,

I tried as you suggested. Unfortunately I get no result when I click on the button.
In my console, it however shows the message
"Tabpanel: tab_main addTab() called with a tabname: frm_navigation_bar_items that is already used"

Any thoughts?

Regards,
Hareendra
hareendra
 
Posts: 98
Joined: Wed Sep 17, 2008 11:41 am

Re: How to create elments in a loop

Postby hareendra » Mon Aug 25, 2014 1:38 pm

Hi Robert,

So I tried the first method you suggested and I got a successful result!
Code: Select all
var jsFunction,
   jsButton,
    row,
    sLastForm;

   for (var index = 1; index <= dsDataset.getMaxRowIndex(); index++) {
      
      row  = dsDataset.getRowAsArray(index);           
      if ( sLastForm != row[1] ) {
           // Get the new method definition
           jsFunction = jsform.newMethod('function  onActionTab'+index+'() { \
                                           forms.frm_main.elements.tab_main.removeAllTabs(); \
                                           forms.frm_main.elements.tab_main.addTab("' + row[1] +'"); \
                                           }');
           // remember which form we last processed
           sLastForm = row[1];
       }   
            
      jsButton = jsform.newButton(row[0], (2 + (index * 120)), 10, 110, 20, jsFunction);   
      jsButton.styleClass    = 'tab';
      jsButton.showClick   = false;            
   }


Thank you so much for your time and patience.

Regards,
Hareendra
hareendra
 
Posts: 98
Joined: Wed Sep 17, 2008 11:41 am


Return to Forms

Who is online

Users browsing this forum: No registered users and 7 guests

cron