you're missing one more indirection, your template will see the name "add" if you pass it in as {'add'=>\%foo}. The following runs fine and does the right thing:
use strict;
use Template;
my %add=(
hsh1=>{
name=>"name1 ",
type =>"text",
default=>" ",
value=>[" "],
entries=>"M"
},
hsh2=>{
name=>"name2 ",
type=>"dropdown",
req=>"prc",
default=>" ",
value=>["value1","value2","value3"],
entries=>" "
}
);
my $template = Template->new();
$template->process(\*DATA,{'add'=>\%add},\*STDOUT)
|| die $template->error();
__DATA__
[% FOREACH element = add.keys %]
[% IF add.$element.type == "text" %]
<input type="text" name="[% add.$element.name %]" value="[% add.$e
+lement.default %]">
[% ELSIF add.$element.type == "dropdown" %]
<select name="[% add.$element.name %]">
[% FOREACH option = add.$element.value %]
<option value="[% option %]">
[% option %]
</option>
[% END %]
</select>
[% END %]
<br> [% # put a line break between the form elements %]
[% END %]
__OUTPUT__
<select name="name2 ">
<option value="value1">
value1
</option>
<option value="value2">
value2
</option>
<option value="value3">
value3
</option>
</select>
<br>
<input type="text" name="name1 " value=" ">
<br>