"Live" calculation of fields in Formbuilder forms [Solved]

Have a question or a suggestion about a 3rd party addon module or plugin?
Let us know here.
Post Reply
Niklas Falk
New Member
New Member
Posts: 8
Joined: Thu Jun 26, 2008 8:57 pm

"Live" calculation of fields in Formbuilder forms [Solved]

Post by Niklas Falk »

I have not found exactly my issue (or a solution that I could transcode as a nice solution) while searching.

I have a couple of forms where I want the user to get some fields calculated before submitting the form. The calculations are complex (at least for some users) so it's an advantage to be able to play with the fields to make it visible (so calculating while submitting is not the solution).

Currently I have placed a javascript in the Form template which refer directly to the form and objects through getElementById(m71af8moduleform_4').m71af8fbrp__136.value etc.
I also set the calculated values at the end with getElementById(m71af8moduleform_4').m71af8fbrp__141.value = calulated_value .

Everything works http://www.spvm.se/index.php?page=modsp ... eklaration but I have a problem with the form name and object references seem to change when I add a new form or rename it in the Formbuilder interface.

Code: Select all

{literal}
function RecalcWeight(){
v_form = document.getElementById('m71af8moduleform_4');
m_klass = v_form.m71af8fbrp__129.selectedIndex;
m_standardeffekt = v_form.m71af8fbrp__136.value;
m_verkligvikt = v_form.m71af8fbrp__149.value;
m_standard = v_form.m71af8fbrp__137.checked
m_slagvolym = v_form.m71af8fbrp__138.value;
m_typ = v_form.m71af8fbrp__139.selectedIndex;
m_fuel = v_form.m71af8fbrp__140.selectedIndex;

     if (m_klass == 1)  {m_klassfaktor = 2.5;}
else if (m_klass == 2)  {m_klassfaktor = 3.2;}
else if (m_klass == 3)  {m_klassfaktor = 5;}
else {m_klassfaktor = 0;}

     if (m_typ==1 && m_fuel==1) {m_table = 80;}
else if (m_typ==1 && m_fuel==2) {m_table = 85;}
else if (m_typ==1 && m_fuel==3) {m_table = 90;}
else if (m_typ==1 && m_fuel==4) {m_table = 150;}
else if (m_typ==2 && m_fuel==1) {m_table = 100;}
else if (m_typ==2 && m_fuel==2) {m_table = 105;}
else if (m_typ==2 && m_fuel==3) {m_table = 110;}
else if (m_typ==2 && m_fuel==4) {m_table = 170;}
else if (m_typ==3 && m_fuel==5) {m_table = 90*1.8;}
else if (m_typ==3 && m_fuel==6) {m_table = 120*1.8;}
else if (m_typ==3 && m_fuel==7) {m_table = 180*1.8;}
else {m_table = 0;}

m_tavlingseffekt = Math.round(m_table * m_slagvolym / 1000);

if (m_standard) {m_tavlingseffekt = m_standardeffekt;}

m_Minvikt1 = Math.round(m_tavlingseffekt * 2.5);
m_Minvikt2 = Math.round(m_tavlingseffekt * 3.2);
m_Minvikt3 = Math.round(m_tavlingseffekt * 5);
m_vikteffekt = Math.round(m_verkligvikt / m_tavlingseffekt * 100)/100;

v_form.m71af8fbrp__141.value = m_tavlingseffekt;
v_form.m71af8fbrp__146.value = m_Minvikt1;
v_form.m71af8fbrp__147.value = m_Minvikt2;
v_form.m71af8fbrp__148.value = m_Minvikt3;
v_form.m71af8fbrp__150.value = m_vikteffekt;
}
{/literal}
Script is called onChange for the fields in question.

Is there a way to pick up the form name and the objects therein as variables that can be used in the Javascript?
If there were I could use this without adding validations in the script (to warn me when objects suddenly are "missing").
There are at least 4 different forms on the final page (but only one Formbuilder form).

Hmm... Maybe I could loop through all objects and pick out the objects with "__##" in its names?
I have no problem with needing to use the database IDs of the fields since these are constant (and formbuilder-unique) after the field have been created.
Damn, it actually works :)

Code: Select all

<__script__ language="JavaScript" type="text/javascript">
{literal}
function RecalcWeight(){
var allTags=document.getElementsByTagName('*'), i=0, e, field_klass, field_standardeffekt, field_standard, field_slagvolym, field_typ, field_fuel, field_tavlingseffekt, field_minvikt1,field_minvikt2, field_minvikt3, field_verkligvikt, field_vikteffekt;

while(e=allTags[i++]){
  if (e.id != null){
    if (e.id.slice(-5) == '__129'){field_klass=e;}
    if (e.id.slice(-5) == '__136'){field_standardeffekt=e;}
    if (e.id.slice(-4) == '_137'){field_standard=e;}
    if (e.id.slice(-5) == '__138'){field_slagvolym=e;}
    if (e.id.slice(-5) == '__139'){field_typ=e;}
    if (e.id.slice(-5) == '__140'){field_fuel=e;}
    if (e.id.slice(-5) == '__141'){field_tavlingseffekt=e;}
    if (e.id.slice(-5) == '__146'){field_minvikt1=e;}
    if (e.id.slice(-5) == '__147'){field_minvikt2=e;}
    if (e.id.slice(-5) == '__148'){field_minvikt3=e;}
    if (e.id.slice(-5) == '__149'){field_verkligvikt=e;}
    if (e.id.slice(-5) == '__150'){field_vikteffekt=e;}
  }
}

m_klass = field_klass.selectedIndex;
m_standardeffekt = field_standardeffekt.value;
m_verkligvikt = field_verkligvikt.value;
m_standard = field_standard.checked;
m_slagvolym = field_slagvolym.value;
m_typ = field_typ.selectedIndex;
m_fuel = field_fuel.selectedIndex;

     if (m_klass == 1)  {m_klassfaktor = 2.5;}
else if (m_klass == 2)  {m_klassfaktor = 3.2;}
else if (m_klass == 3)  {m_klassfaktor = 5;}
else {m_klassfaktor = 0;}

     if (m_typ==1 && m_fuel==1) {m_table = 80;}
else if (m_typ==1 && m_fuel==2) {m_table = 85;}
else if (m_typ==1 && m_fuel==3) {m_table = 90;}
else if (m_typ==1 && m_fuel==4) {m_table = 150;}
else if (m_typ==2 && m_fuel==1) {m_table = 100;}
else if (m_typ==2 && m_fuel==2) {m_table = 105;}
else if (m_typ==2 && m_fuel==3) {m_table = 110;}
else if (m_typ==2 && m_fuel==4) {m_table = 170;}
else if (m_typ==3 && m_fuel==5) {m_table = 90*1.8;}
else if (m_typ==3 && m_fuel==6) {m_table = 120*1.8;}
else if (m_typ==3 && m_fuel==7) {m_table = 180*1.8;}
else {m_table = 0;}

m_tavlingseffekt = Math.round(m_table * m_slagvolym / 1000);

if (m_standard) {m_tavlingseffekt = m_standardeffekt;}

m_Minvikt1 = Math.round(m_tavlingseffekt * 2.5);
m_Minvikt2 = Math.round(m_tavlingseffekt * 3.2);
m_Minvikt3 = Math.round(m_tavlingseffekt * 5);
m_vikteffekt = Math.round(m_verkligvikt / m_tavlingseffekt * 100)/100;

field_tavlingseffekt.value = m_tavlingseffekt;
field_minvikt1.value = m_Minvikt1;
field_minvikt2.value = m_Minvikt2;
field_minvikt3.value = m_Minvikt3;
field_vikteffekt.value = m_vikteffekt;
}
{/literal}
</__script>
This is of course poor logic if there are multiple objects on the page with id's ending with "__###" but this make it possible for me to sleep a bit easier when playing around with the next form since the previous ones will still work.

A real nice feature would be if the Formbuilder forms could include a Javascript object that could use the smarty variables to refer to the fields (it's the module that assign the final names of the form and objects I guess).

So an issue [Solved] while typing the question, but submitted for sharing and comments.
Last edited by Niklas Falk on Mon Aug 09, 2010 2:05 pm, edited 1 time in total.
Niklas Falk
New Member
New Member
Posts: 8
Joined: Thu Jun 26, 2008 8:57 pm

Re: "Live" calculation of fields in Formbuilder forms [Solved]

Post by Niklas Falk »

Oh, well, upgraded to latest FormBuilder (0.6.3) and now there is a variable for the "input_id", exactly what I was after.

So now I can use document.getElementById('{$entry->input_id}') to define all the variables.
To use Smarty code within a javascript I just disable {literal} for that part.

Code: Select all

{* SCRIPT for calulating things between fields *}

{literal}
function RecalcWeight()
{
{/literal}
{* Let's define JS variables based on the object Id's in smarty variables *}
{foreach from=$fields item=entry}
  {if $entry->name == 'Klass'}
    var field_klass = document.getElementById('{$entry->input_id}');
  {/if}
  {if $entry->name == 'Grundeffekt enligt tillverkarspec'}
    var field_standardeffekt = document.getElementById('{$entry->input_id}');
  {/if}
  {if $entry->name == 'Är Motorn Standard?'}
    var field_standard = document.getElementById('{$entry->input_id}');
  {/if}
  {if $entry->name == 'Verklig Slagvolym (cc)'}
    var field_slagvolym = document.getElementById('{$entry->input_id}');
  {/if}
  {if $entry->name == 'Motortyp'}
    var field_typ = document.getElementById('{$entry->input_id}');
  {/if}
  {if $entry->name == 'Bränslesystem'}
    var field_fuel = document.getElementById('{$entry->input_id}');
  {/if}
  {if $entry->name == 'Tävlingseffekt'}
    var field_tavlingseffekt = document.getElementById('{$entry->input_id}');
  {/if}
  {if $entry->name == 'MinimiVikt Modsport I'}
    var field_minvikt1 = document.getElementById('{$entry->input_id}');
  {/if}
  {if $entry->name == 'MinimiVikt Modsport II'}
    var field_minvikt2 = document.getElementById('{$entry->input_id}');
  {/if}
  {if $entry->name == 'MinimiVikt Modsport III'}
    var field_minvikt3 = document.getElementById('{$entry->input_id}');
  {/if}
  {if $entry->name == 'Verklig Vikt'}
    var field_verkligvikt = document.getElementById('{$entry->input_id}');
  {/if}
  {if $entry->name == 'Verklig Vikt/Effekt'}
    var field_vikteffekt = document.getElementById('{$entry->input_id}');
  {/if}
{/foreach}
{literal}

m_klass = field_klass.selectedIndex;
m_standardeffekt = field_standardeffekt.value;
m_verkligvikt = field_verkligvikt.value;
m_standard = field_standard.checked;
m_slagvolym = field_slagvolym.value;
m_typ = field_typ.selectedIndex;
m_fuel = field_fuel.selectedIndex;

      if (m_klass == 1)  {m_klassfaktor = 2.5;}
else if (m_klass == 2)  {m_klassfaktor = 3.2;}
else if (m_klass == 3)  {m_klassfaktor = 5;}
else {m_klassfaktor = 0;}

      if (m_typ==1 && m_fuel==1) {m_table = 80;}
else if (m_typ==1 && m_fuel==2) {m_table = 85;}
else if (m_typ==1 && m_fuel==3) {m_table = 90;}
else if (m_typ==1 && m_fuel==4) {m_table = 150;}
else if (m_typ==2 && m_fuel==1) {m_table = 100;}
else if (m_typ==2 && m_fuel==2) {m_table = 105;}
else if (m_typ==2 && m_fuel==3) {m_table = 110;}
else if (m_typ==2 && m_fuel==4) {m_table = 170;}
else if (m_typ==3 && m_fuel==5) {m_table = 90*1.8;}
else if (m_typ==3 && m_fuel==6) {m_table = 120*1.8;}
else if (m_typ==3 && m_fuel==7) {m_table = 180*1.8;}
else {m_table = 0;}

m_tavlingseffekt = Math.round(m_table * m_slagvolym / 1000);

if (m_standard) {m_tavlingseffekt = m_standardeffekt;}

m_Minvikt1 = Math.round(m_tavlingseffekt * 2.5);
m_Minvikt2 = Math.round(m_tavlingseffekt * 3.2);
m_Minvikt3 = Math.round(m_tavlingseffekt * 5);
m_vikteffekt = Math.round(m_verkligvikt / m_tavlingseffekt * 100)/100;

field_tavlingseffekt.value = m_tavlingseffekt;
field_minvikt1.value = m_Minvikt1;
field_minvikt2.value = m_Minvikt2;
field_minvikt3.value = m_Minvikt3;
field_vikteffekt.value = m_vikteffekt;

}
{/literal}
So now I only need to enter the Field Names in the Script regardless of their ID (or form name).
This would in principle mean that I can export and import the form as XML and the new copy would also work, without any editing  :o :D
Last edited by Niklas Falk on Mon Aug 09, 2010 3:44 pm, edited 1 time in total.
Post Reply

Return to “Modules/Add-Ons”