You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@velocity.apache.org by Tom Bednarz <li...@bednarz.ch> on 2004/03/23 18:21:14 UTC

Problems calling Velocity code from JavaScript function

I don't know if the following is possible:

I use Velocity and Struts.

I generate a logon form that has several Logon Providers listet in a
ComboBox (<SELECT> object).

When the user selects a logon provider from the list, a second ComboBox
should be filled with Logon Domains if there are any.

I do have a Hashtable of LogonProviders. Each Hashtable entry is a Vector of
logon domains. So I like to use velocity to populate the second list. Since
this depends on the selection in the first list I defined a onselect()
handler in the <SELECT> object. This handler calls a JavaScript function
which should populate the second combobox. I get an error from the
VelocityViewServlet.

Here the code:

 <script LANGUAGE="JavaScript">
    loadStyleSheet()
    function listLogonDomains()
    {
        var Provider =
document.LogonForm.AuthenticationProvider.options[document.LogonForm.Authent
icationProvider.selectedIndex].value;
        var DomainList = "";
        alert(DomainList);
        #foreach($Domain in $LogonDomains.get(Provider))
            DomainList += "; ";
            DomainList += $Domain;
        #end

        alert(DomainList);
    }
    </script>

The alert is just for debugging!


<form name="LogonForm" action=$link.setURI("$appRoot/authenticate.do")
METHOD=POST  >
<table align="center" cellspacing="2" cellpadding="2" border="0">
<tr>
    <td rowspan="5"><img src="$appRoot/Images/Logon.gif" width="192"
height="146" border="0" alt=""></td>
    <td width="200" id="FormFont">Authentication Provider:</td>
 <td width="200" id="FormFont"><select name="AuthenticationProvider"
size="1" onchange="listLogonDomains()">
        <option selected value=""></option>
        #foreach($Provider in $AuthenticationProvider)
            <option value=$Provider>$Provider</option>
        #end
        </select>
 </td>
</tr>
........


The error I get is:

Invocation of method 'get' in  class java.util.Hashtable threw exception
class java.lang.NullPointerException :
nullorg.apache.velocity.exception.MethodInvocationException: Invocation of
method 'get' in  class java.util.Hashtable threw exception class
java.lang.NullPointerException : null
 at
org.apache.velocity.runtime.parser.node.ASTMethod.execute(ASTMethod.java:309
)

It happens when loading the page (done through a Struts action servlet). The
same code works just perfect when NOT called in the JavaScript function.

Can Velocity template code be called in JavaScript functions?

Thanks for your help

Thomas


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: Problems calling Velocity code from JavaScript function

Posted by Tom Bednarz <li...@bednarz.ch>.
Hello Simon,

Many thanks for the detailed answer. Its clear why it does not work. The
data is rather small (up to a dozen elements) so I try to follow your
suggested approach.

Thanks again!
Thomas
----- Original Message ----- 
From: "Simon Christian" <si...@stoutstick.com>
To: "Velocity Users List" <ve...@jakarta.apache.org>
Sent: Tuesday, March 23, 2004 6:38 PM
Subject: Re: Problems calling Velocity code from JavaScript function


> You need to recognize the distinction that Velocity acts purely on the
> server side, and Javascript acts (most of the time, including this case)
> on the client side i.e. the browser. Therefore you cannot access your
> context elements from within Javascript.
>
> There's two ways around this:
>
> (i) At the onChange event, reload the page to list the appropriate domains
>
> (ii) Pre-populate a Javascript data structure when generating the page.
> This is only really suitable when you don't have a lot of data, but you
> could do something like this:
>
>
> <script type="text/javascript">
> <!--
>
> // providerLookup contains provider names as keys to arrays of domains
> var providerLookup = new Array();
> #foreach($Provider in $AuthenticationProvider)
> providerLookup['$Provider'] = new Array();
> #foreach($Domain in $LogonDomains.get(Provider))
> #set( $_domindex = $velocityCount - 1 )
> providerLookup['$Provider'][$_domindex] = $Domain;
> #end
> #end
>
> function listLogonDomains()
> {
>    // assign the dropdown to an easier-to-reference variable
>    var selectBox = document.LogonForm.AuthenticationProvider;
>    var provider = selectBox.options[selectBox.selectedIndex].value;
>    var domainArray = providerLookup[provider];
>
>    // this bit purely for debugging
>    var domainList = "";
>    for( var kk = 0; kk < domainArray.length; kk++ )
>    {
>      if( kk > 0 )
>      {
>        domainList += ",";
>      }
>      domainList += domainArray[kk];
>    }
>    alert(DomainList);
>
>    // populate the target pulldown...
> }
>
> // -->
> </script>
>
> You could do it a bit more elegantly with custom objects in Javascript,
> but that should give the essence of it.
>
> - simon
>
>
> Tom Bednarz wrote:
> > I don't know if the following is possible:
> >
> > I use Velocity and Struts.
> >
> > I generate a logon form that has several Logon Providers listet in a
> > ComboBox (<SELECT> object).
> >
> > When the user selects a logon provider from the list, a second ComboBox
> > should be filled with Logon Domains if there are any.
> >
> > I do have a Hashtable of LogonProviders. Each Hashtable entry is a
Vector of
> > logon domains. So I like to use velocity to populate the second list.
Since
> > this depends on the selection in the first list I defined a onselect()
> > handler in the <SELECT> object. This handler calls a JavaScript function
> > which should populate the second combobox. I get an error from the
> > VelocityViewServlet.
> >
> > Here the code:
> >
> >  <script LANGUAGE="JavaScript">
> >     loadStyleSheet()
> >     function listLogonDomains()
> >     {
> >         var Provider =
> >
document.LogonForm.AuthenticationProvider.options[document.LogonForm.Authent
> > icationProvider.selectedIndex].value;
> >         var DomainList = "";
> >         alert(DomainList);
> >         #foreach($Domain in $LogonDomains.get(Provider))
> >             DomainList += "; ";
> >             DomainList += $Domain;
> >         #end
> >
> >         alert(DomainList);
> >     }
> >     </script>
> >
> > The alert is just for debugging!
> >
> >
> > <form name="LogonForm" action=$link.setURI("$appRoot/authenticate.do")
> > METHOD=POST  >
> > <table align="center" cellspacing="2" cellpadding="2" border="0">
> > <tr>
> >     <td rowspan="5"><img src="$appRoot/Images/Logon.gif" width="192"
> > height="146" border="0" alt=""></td>
> >     <td width="200" id="FormFont">Authentication Provider:</td>
> >  <td width="200" id="FormFont"><select name="AuthenticationProvider"
> > size="1" onchange="listLogonDomains()">
> >         <option selected value=""></option>
> >         #foreach($Provider in $AuthenticationProvider)
> >             <option value=$Provider>$Provider</option>
> >         #end
> >         </select>
> >  </td>
> > </tr>
> > ........
> >
> >
> > The error I get is:
> >
> > Invocation of method 'get' in  class java.util.Hashtable threw exception
> > class java.lang.NullPointerException :
> > nullorg.apache.velocity.exception.MethodInvocationException: Invocation
of
> > method 'get' in  class java.util.Hashtable threw exception class
> > java.lang.NullPointerException : null
> >  at
> >
org.apache.velocity.runtime.parser.node.ASTMethod.execute(ASTMethod.java:309
> > )
> >
> > It happens when loading the page (done through a Struts action servlet).
The
> > same code works just perfect when NOT called in the JavaScript function.
> >
> > Can Velocity template code be called in JavaScript functions?
> >
> > Thanks for your help
> >
> > Thomas
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: velocity-user-help@jakarta.apache.org
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: velocity-user-help@jakarta.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: Problems calling Velocity code from JavaScript function

Posted by Simon Christian <si...@stoutstick.com>.
You need to recognize the distinction that Velocity acts purely on the 
server side, and Javascript acts (most of the time, including this case) 
on the client side i.e. the browser. Therefore you cannot access your 
context elements from within Javascript.

There's two ways around this:

(i) At the onChange event, reload the page to list the appropriate domains

(ii) Pre-populate a Javascript data structure when generating the page. 
This is only really suitable when you don't have a lot of data, but you 
could do something like this:


<script type="text/javascript">
<!--

// providerLookup contains provider names as keys to arrays of domains
var providerLookup = new Array();
#foreach($Provider in $AuthenticationProvider)
providerLookup['$Provider'] = new Array();
#foreach($Domain in $LogonDomains.get(Provider))
#set( $_domindex = $velocityCount - 1 )
providerLookup['$Provider'][$_domindex] = $Domain;
#end
#end

function listLogonDomains()
{
   // assign the dropdown to an easier-to-reference variable
   var selectBox = document.LogonForm.AuthenticationProvider;
   var provider = selectBox.options[selectBox.selectedIndex].value;
   var domainArray = providerLookup[provider];

   // this bit purely for debugging
   var domainList = "";
   for( var kk = 0; kk < domainArray.length; kk++ )
   {
     if( kk > 0 )
     {
       domainList += ",";
     }
     domainList += domainArray[kk];
   }
   alert(DomainList);

   // populate the target pulldown...
}

// -->
</script>

You could do it a bit more elegantly with custom objects in Javascript, 
but that should give the essence of it.

- simon


Tom Bednarz wrote:
> I don't know if the following is possible:
> 
> I use Velocity and Struts.
> 
> I generate a logon form that has several Logon Providers listet in a
> ComboBox (<SELECT> object).
> 
> When the user selects a logon provider from the list, a second ComboBox
> should be filled with Logon Domains if there are any.
> 
> I do have a Hashtable of LogonProviders. Each Hashtable entry is a Vector of
> logon domains. So I like to use velocity to populate the second list. Since
> this depends on the selection in the first list I defined a onselect()
> handler in the <SELECT> object. This handler calls a JavaScript function
> which should populate the second combobox. I get an error from the
> VelocityViewServlet.
> 
> Here the code:
> 
>  <script LANGUAGE="JavaScript">
>     loadStyleSheet()
>     function listLogonDomains()
>     {
>         var Provider =
> document.LogonForm.AuthenticationProvider.options[document.LogonForm.Authent
> icationProvider.selectedIndex].value;
>         var DomainList = "";
>         alert(DomainList);
>         #foreach($Domain in $LogonDomains.get(Provider))
>             DomainList += "; ";
>             DomainList += $Domain;
>         #end
> 
>         alert(DomainList);
>     }
>     </script>
> 
> The alert is just for debugging!
> 
> 
> <form name="LogonForm" action=$link.setURI("$appRoot/authenticate.do")
> METHOD=POST  >
> <table align="center" cellspacing="2" cellpadding="2" border="0">
> <tr>
>     <td rowspan="5"><img src="$appRoot/Images/Logon.gif" width="192"
> height="146" border="0" alt=""></td>
>     <td width="200" id="FormFont">Authentication Provider:</td>
>  <td width="200" id="FormFont"><select name="AuthenticationProvider"
> size="1" onchange="listLogonDomains()">
>         <option selected value=""></option>
>         #foreach($Provider in $AuthenticationProvider)
>             <option value=$Provider>$Provider</option>
>         #end
>         </select>
>  </td>
> </tr>
> ........
> 
> 
> The error I get is:
> 
> Invocation of method 'get' in  class java.util.Hashtable threw exception
> class java.lang.NullPointerException :
> nullorg.apache.velocity.exception.MethodInvocationException: Invocation of
> method 'get' in  class java.util.Hashtable threw exception class
> java.lang.NullPointerException : null
>  at
> org.apache.velocity.runtime.parser.node.ASTMethod.execute(ASTMethod.java:309
> )
> 
> It happens when loading the page (done through a Struts action servlet). The
> same code works just perfect when NOT called in the JavaScript function.
> 
> Can Velocity template code be called in JavaScript functions?
> 
> Thanks for your help
> 
> Thomas
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: velocity-user-help@jakarta.apache.org
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org