Dynamic form with JavaScript

Informations

Author: Denis Van Nuffelen
License: FPDF

Description

This script allows to generate forms dynamically when the document opens by the means of some JavaScript code (it requires the JavaScript support extension).

Caution: the generated PDF works only with Acrobat Reader 5.1.

It is possible to create text fields, combo boxes, check boxes and buttons. Fields are created at the current position and are given a name. This name allows to manipulate them via JavaScript in order to perform some validation for instance.
Upon field creation, an associative array can be passed to set a number of properties, among which:

TextColor (black by default)
FillColor (transparent by default)
BorderColor (transparent by default)
BorderStyle (solid, dashed, beveled, inset or underline; solid by default)

Colors can be chosen in the following list (case sensitive):

black white red green blue cyan magenta yellow dkGray gray ltGray

or be in the form #RRGGBB.

Methods to create fields are the following:

TextField(string name, float w, float h [, array prop])

name: field name.
w: width.
h: height.
prop: properties. The value property allows to set the initial value. The multiline property allows to define the field as multiline.

ComboBox(string name, float w, float h, array values [, array prop])

name: combobox name.
w: width.
h: height.
values: array containing the list of values.
prop: properties.

CheckBox(string name, float w [, boolean checked [, array prop]])

name: checkbox name.
w: width.
checked: boolean defining the initial state (false by default).
prop: properties.

Button(string name, float w, float h, string caption, string action [, array prop])

name: button name.
w: width.
h: height.
caption: caption.
action: action triggered by the button (JavaScript code).
prop: properties.

The JavaScript is being generated and added to the script property of the objet each time you call one of these methods.

Source

<?php
require('fpdf_js.php');

class 
JS_Form extends PDF_Javascript
{
var 
$script='';

function 
_JScolor($color)
{
    static 
$aColors=array('transparent','black','white','red','green','blue','cyan','magenta',
        
'yellow','dkGray','gray','ltGray');

    if(
substr($color,0,1)=='#')
    {
        return 
sprintf("['RGB',%.3f,%.3f,%.3f]"hexdec(substr($color,1,2))/255,
            
hexdec(substr($color,3,2))/255hexdec(substr($color,5,2))/255);
    }
    if(!
in_array($color,$aColors))
        
$this->Error('Invalid color: '.$color);
    return 
'color.'.$color;
}

function 
_addfield($type,$name,$x,$y,$w,$h,$prop)
{
    
$k=$this->k;
    
$this->script.=sprintf("f=addField('%s','%s',%d,[%.2f,%.2f,%.2f,%.2f]);",
        
$name,$type,$this->PageNo()-1,$x*$k,($this->h-$y)*$k+1,($x+$w)*$k,($this->h-$y-$h)*$k+1);
    
$this->script.='f.textSize='.$this->FontSizePt.';';
    if(isset(
$prop['value']))
        
$this->script.="f.value='".addslashes($prop['value'])."';";
    if(isset(
$prop['TextColor']))
        
$this->script.='f.textColor='.$this->_JScolor($prop['TextColor']).';';
    if(isset(
$prop['FillColor']))
        
$this->script.='f.fillColor='.$this->_JScolor($prop['FillColor']).';';
    if(isset(
$prop['BorderColor']))
        
$this->script.='f.strokeColor='.$this->_JScolor($prop['BorderColor']).';';
    if(isset(
$prop['BorderStyle']))
        
$this->script.="f.borderStyle='".$prop['BorderStyle']."';";
    
$this->x+=$w;
}

function 
TextField($name,$w,$h,$prop=array())
{
    
$this->_addfield('text',$name,$this->x,$this->y,$w,$h,$prop);
    if(isset(
$prop['multiline']) and $prop['multiline'])
        
$this->script.='f.multiline=true;';
}

function 
ComboBox($name,$w,$h,$values,$prop=array())
{
    
$this->_addfield('combobox',$name,$this->x,$this->y,$w,$h,$prop);
    
$s='';
    foreach(
$values as $value)
        
$s.="'".addslashes($value)."',";
    
$this->script.='f.setItems(['.substr($s,0,-1).']);';
}

function 
CheckBox($name,$w,$checked=false,$prop=array())
{
    
$prop['value']=($checked 'Yes' 'Off');
    if(!isset(
$prop['BorderColor']))
        
$prop['BorderColor']='black';
    
$this->_addfield('checkbox',$name,$this->x,$this->y,$w,$w,$prop);
}

function 
Button($name,$w,$h,$caption,$action,$prop=array())
{
    if(!isset(
$prop['BorderColor']))
        
$prop['BorderColor']='black';
    
$prop['BorderStyle']='beveled';
    
$this->_addfield('button',$name,$this->x,$this->y,$w,$h,$prop);
    
$this->script.="f.buttonSetCaption('".addslashes($caption)."');";
    
$this->script.="f.setAction('MouseUp','".addslashes($action)."');";
    
$this->script.="f.highlight='push';";
    
$this->script.='f.print=false;';
}
}
?>

Example

Here is an example which creates a form with the different possible field types. When one clicks on the button, the mandatory fields are checked, and, if validation passes, the page is printed.

<?php
define
('FPDF_FONTPATH','font/');
require(
'js_form.php');

$pdf=new JS_Form();
$pdf->Open();
$pdf->AddPage();

//Title
$pdf->SetFont('Arial','U',16);
$pdf->Cell(0,5,'Subscription form',0,1,'C');
$pdf->Ln(10);
$pdf->SetFont('','',12);
//First name
$pdf->Cell(35,5,'First name:');
$pdf->TextField('firstname',50,5,array('BorderColor'=>'ltGray'));
$pdf->Ln(6);
//Last name
$pdf->Cell(35,5,'Last name:');
$pdf->TextField('lastname',50,5,array('BorderColor'=>'ltGray'));
$pdf->Ln(6);
//Gender
$pdf->Cell(35,5,'Gender:');
$pdf->ComboBox('gender',10,5,array('','M','F'),array('BorderColor'=>'ltGray'));
$pdf->Ln(6);
//Adress
$pdf->Cell(35,5,'Address:');
$pdf->TextField('address',60,18,array('multiline'=>true,'BorderColor'=>'ltGray'));
$pdf->Ln(19);
//E-mail
$pdf->Cell(35,5,'E-mail:');
$pdf->TextField('email',50,5,array('BorderColor'=>'ltGray'));
$pdf->Ln(6);
//Newsletter
$pdf->Cell(35,5,'Receive our',0,1);
$pdf->Cell(35,5,'newsletter:');
$pdf->CheckBox('newsletter',5,true);
$pdf->Ln(10);
//Date of the day (determined and formatted by JS)
$pdf->Write(5,'Date: ');
$pdf->TextField('date',30,5);
$pdf->script.="getField('date').value=util.printd('dd/mm/yyyy',new Date());";
$pdf->Ln();
$pdf->Write(5,'Signature:');
$pdf->Ln(3);
//Button to validate and print
$pdf->SetX(95);
$pdf->Button('print',20,8,'Print','Print()',array('TextColor'=>'yellow','FillColor'=>'#FF5050'));

//Form validation functions
$pdf->script.="
function CheckField(name,message)
{
    f=getField(name);
    if(f.value=='')
    {
        app.alert(message);
        f.setFocus();
        return false;
    }
    return true;
}

function Print()
{
    //Validation
    if(!CheckField('firstname','First name is mandatory'))
        return;
    if(!CheckField('lastname','Last name is mandatory'))
        return;
    if(!CheckField('gender','Gender is mandatory'))
        return;
    if(!CheckField('address','Address is mandatory'))
        return;
    //Print
    print();
}
"
;

//We include all the generated JavaScript code into the PDF
$pdf->IncludeJS($pdf->script);
$pdf->Output();
?>

View the result here.

Download

ZIP | TGZ