Using Uploadify in Frontend Forms
30 Aug
Since its release last week, Uploadify fever has really caught on. I couldn’t be happier to see that! I have a lot of plans for Uploadify, including integrating it with the DataObjectManager module, and continuing to refine the authentication and Amazon S3 features.
But for today, I thought it would be worthwhile to give a tutorial on integrating Uploadify into the front end. Uploadify fields are just as easy to use on the frontend as they are in the backend. No extra configuration is needed. A different template is automatically used for the frontend, and administrative features such as folder selection and file importing are removed.
In this example, we will create a job application form. We will collect a single resume and several letters of recommendation. The resumes will be limited to PDFs and recommendations will be limited to .doc or .docx. The form will store the application in the database for an administrator to view later.
Step 1: Create the Job Application object
The form will save into an object so that it can be stored in the database.
// JobApplication.php //
class JobApplication extends DataObject
{
static $db = array (
'FirstName' => 'Text',
'LastName' => 'Text',
'Email' => 'Text',
'Position' => "Enum('Sales, Marketing, Logistics')"
);
static $has_one = array (
'Resume' => 'File'
);
static $has_many = array (
'Recommendations' => 'RecommendationFile'
);
}
Because we have a $has_many relationship for files, we need to create a File subclass to create the $has_one back to JobApplication. This is not necessary for Resume, because there is only one of those allowed.
// RecommendationFile.php //
class RecommendationFile extends File
{
static $has_one = array (
'JobApplication' => 'JobApplication',
'StaffMemberPage' => 'StaffMemberPage'
);
}
Now it is necessary to run a /dev/build, and make sure the database gets updated.
Step 2: Build the form
We’ll create a new page type to display the form.
// JobApplicationPage.php //
class JobApplicationPage extends Page
{
}
class JobApplicationPage_Controller extends Page_Controller
{
public function ApplyForm() {
$form = new Form (
$this,
"ApplyForm",
new FieldSet (
new TextField('FirstName', _t('JobApplication.FIRSTNAME','First name')),
new TextField('LastName', _t('JobApplication.LASTNAME','Last name')),
new EmailField('Email', _t('JobApplication.EMAIL','Email')),
new DropdownField('Position', _t('JobApplication.POSITION','Position applying for'), singleton('JobApplication')->dbObject('Position')->enumValues()),
$resume = new FileUploadField('Resume', _t('JobApplication.RESUME','Upload a resume')),
$recommendations = new MultipleFileUploadField('Recommendations', _t('JobApplication.RECOMMENDATIONS','Upload several letters of recommendation'))
),
new FieldSet (
new FormAction('doApply', _t('JobApplication.APPLYNOW','Apply now'))
),
new RequiredFields('FirstName','LastName','Email','Position')
);
$resume->setFileTypes(array(
'pdf'
));
$recommendations->setFileTypes(array(
'doc',
'docx'
));
return $form;
}
}
Here we have a pretty straightforward form, but the important thing to notice is that all of the field names are consistent with those of the JobApplication object, e.g. “FirstName, “Position”, etc. This is because the form will save into the JobApplication dataobject. If we were not doing that, this consistency would not be necessary.
Notice that the form action “doApply” is specified in the actions FieldSet, but it has not been defined. That will be the next step.
Step 3: Handle the form
Create the following action in JobApplicationPage_Controller class.
// JobApplicationPage.php //
public function doApply($data, $form) {
$form->saveInto($application = new JobApplication());
$application->write();
return array (
'Application' => $application
);
}
This really simple handler is all we need to save a form whose fields are already in alignment with the JobApplication dataobject. If we were not saving the data to a the database, we might do something like this:
public function doApply($data, $form) {
$from = $data['Email'];
$to = "administrator@mysite.com";
$subject = "New job application";
$body = "Someone submitted a job application. The files are attached.";
$email = new Email($from, $to, $subject, $body);
if(isset($data['ResumeID'])) {
if($file = DataObject::get_by_id("File", (int) $data['ResumeID'])) {
$email->attachFile($file->getFullPath(), $file->Name);
}
}
if(isset($data['Recommendations']) && is_array($data['Recommendations'])) {
foreach($data['Recommendations'] as $id) {
if($file = DataObject::get_by_id("File", (int) $id)) {
$email->attachFile($file->getFullPath(), $file->Name);
}
}
}
$email->send();
$form->sessionMessage("Thank you for submitting your application","good");
return Director::redirectBack();
}
Notice that the single file is sent as [RelationshipName]ID, but the multiple file relation is sent as an array of IDs under the name [Relationship].
Let’s look again at the first doApply() function. The return value is an array containing the application object.
return array (
'Application' => $application
);
The field “Application” will be available on the template. Let’s examine how we can handle that.
// JobApplicationPage.ss //
$Title
If the application is available, we enter a control and show the components, and prove the integrity of the data by offering a download link.
If the application isn’t available, we simply invoke $ApplyForm to show the form.
That’s it! If you have any questions, please feel free to post a comment. Good luck!




Sweet stuff Uncle Cheese. We are all excited about about uploadify just as you are. Your modules have made Silverstripe more juicy. Thanks a lot.
Hiya UC,
hey…is there some code missing from that last snippet (JobApplicationPage.ss)? You refer to using a control with the ‘Application’ filed, but don’t have it in the code sample…
Cheers
nj
Also, another quick question on this…
I’m getting uploadify errors with code similar to yours above, and have tracked it down to a hidden field in the form:
new HiddenField ($name = “jobvacancynumber”, $title = “jobvacancynumber”,$value = $this->CurrentJob->VacancyNumber)
it outputs fine to the page, but then when I try to upload a file I get the following:
500 Notice: “Trying to get property of non-object” at line 91 of /usr/local/www/vhosts/tdh.org.nz/httpdocs/mysite/code/JobApplicationForm.php (where line 91 is the hiddenfield above)
any ideas??
hi again:) delete that last one….stupid mistake was causing the glitch! I found it using charles – dunno if your familiar with it – web debugging proxy developed by a guy here in NZ – essential! http://www.charlesproxy.com/
I’ve tried this, and it doesn’t work for me on the frontend. Trying with this and my own example the files are uploaded into the assets folder, but there is no ImageID variable available in $data variable.
Using SS 2.4.2. / Uploadify 511.
Debug (JobApplicationPage_Controller->doApply() in line 39 of JobApplicationPage.php)
* url =
/abflags/new-jobapplicationpage/ApplyForm
* FirstName =
Test
* LastName =
test
* Email =
test@example.com
* Position =
Sales
* FolderID =
1
* SecurityID =
12850
* action_doApply =
Apply now
Debug (JobApplicationPage_Controller->doApply() in line 40 of JobApplicationPage.php)
Form
* TextFieldTextField (FirstName: First name : ) = Test
* TextFieldTextField (LastName: Last name : ) = test
* EmailFieldEmailField (Email: Email : ) = test@example.com
* DropdownFieldDropdownField (Position: Position applying for : ) = Sales
* FileUploadFieldFileUploadField (Resume: Upload a resume : ) =
* MultipleFileUploadFieldMultipleFileUploadField (Recommendations: Upload several letters of recommendation : ) =
* HiddenFieldHiddenField (SecurityID: : ) = 12850
Validator
* FirstName
* LastName
* Email
* Position
i have got exactely the same problem. was anybody able to solve this?
Greetings, Carsten.
Same problem here.
Not 100% sure whether it’s the same issue as this post was a while back, but I found that two references to separate jQuery include files causes Uploadify to fail without error. This can simply be resolved by ensuring jQuery is only included once.
I’m running the demos linked from this page
http://dataobjectmanager.carlinowebdesign.com/job-application-page/
http://dataobjectmanager.carlinowebdesign.com/job-application-page-2/
and in each case
– js error
$ is not a function $(‘#Form_ApplyForm’).validate();
when the page loads
– first name field is bounded and shaded red as though there was an error
– no upload behaviour in the file upload parts, ie nothing uploads
– no multiple behaviour in the multiple upload field
I’m running FF3 on ubuntu linux
I wonder if there’s something wrong with the demo site (or the demo site user =] ) because it works much better on my local machine with the downloaded code. I’m getting “IO error” on upload but that’s probably my fault, I’ve not tried any setup at all yet.
Hi Is there a way to doApply via Ajax.submit?
I tried it that way:
jQuery(“#Form_ApplyForm”).submit(function(){
jQuery(‘#Form_ApplyForm’).load(
‘domain/doApply’,{values: jQuery(this).serialize()}…
but don’t know how to get the form-object for saving it into my dataobject
I know doApply needs two values
Found a bug,..
when deleting a file while it is uploading, doesn’t delete the file but all the others which have already been uploaded
Not sure if this is a bug or not, but I’m running SS 2.4.5 and when I put FileUploadField on a front end form and have it upload automatically (not on submit) the file gets uploaded but the file name does not show up under “Attached Files” is just says “No File Attached”.
Is there a way to have the file show up after it uploads.
Also, if I set the uploadOnSubmit and the form doesn’t validate the file gets uploaded still, is there a way to not have that upload unless the form is valid?
I just copy the files that you bring in this post, and i get this error “there has been an error, error loading page”, i actually have a question LOL, the package “uploadify_frontend.zip” has a “templates” folder, where do i have to put this folder…tnks, i hope you can help me.