Display a CCK Filefield or Imagefield Upload Widget on Your Own Custom Form
Took a fair amount of googling around to find the solution to this one. With the Node Gallery 3.x branch, we needed a way to quickly add an image to an existing gallery. We could have displayed the whole node form, but there's a lot of things on that form that we can just use the defaults for 99% of the time. We need just three fields filled in: Title, Caption, and the imagefield itself.
To use the same imagefield widget that handles all the hard work for you on the node add field on your own field, first create a handler in hook_menu such as this:
- 'title' => 'Upload New Image',
- 'page callback' => 'drupal_get_form',
- 'access callback' => 'node_gallery_user_access',
- 'file' => 'node_gallery.pages.inc',
- 'type' => MENU_LOCAL_TASK,
- );
Then, in node_gallery.pages.inc, you create the form function that does the work:
- function node_gallery_upload_image_form($form_state, $gallery) {
- $imagetype = 'node_gallery_image';
- $form_id = $imagetype . '_node_form';
- module_load_include('inc', 'content', 'includes/content.node_form');
- $field = content_fields('field_node_gallery_image',$imagetype);
- '#title' => t('Title'),
- '#type' => 'textfield',
- '#required' => TRUE,
- '#weight' => -10,
- );
- '#title' => t('Caption'),
- '#type' => 'textarea',
- '#weight' => -9,
- );
- '#type' => 'value',
- '#value' => $imagetype,
- );
- '#type' => 'value',
- '#value' => $gallery->nid,
- );
- $form['#field_info']['field_node_gallery_image'] = $field;
- $form['#field_info']['field_node_gallery_image']['#required'] = TRUE;
- return $form;
This is pretty straightforward, up until lines 28 - 30. Those three lines setup the form array and then append the results from content_field_form() to our existing form. Still, very easy, but I wasn't able to find any documentation on how to do this. Just in case you're curious, here's the submit handler for that form.
- function node_gallery_upload_image_form_submit($form, &$form_state) {
- $image = new stdClass;
- $image->uid = $user->uid;
- $values = $form_state['values'];
- foreach ($values as $key => $value) {
- $image->$key = $value;
- }
- node_gallery_image_save($image);
- }
Nothing new there. The end result is a nice looking, concise form that allows you to quickly upload an image to a gallery. Sweet!
- Category:

Comments
Extremely helpful! I've been
Extremely helpful! I've been searching for days looking for this!
I have a quick question though. I've created a module that is basically a front end friendly story node edit form. I added a image field using CCK to the story content type.
Everything works great until submit and then nothing. Here is my submit handler.
function story_form_submit($form, &$form_state) {
global $user;
module_load_include('inc', 'node', 'node.pages');
$node = array('type' => 'story');
$story_form_state = array();
$story_form_state['values']['name'] = $user->name;
$story_form_state['values']['title'] = $form_state['values']['title'];
$story_form_state['values']['field_story_name'][0]['value'] = $form_state['values']['name'];
$story_form_state['values']['field_story_city'][0]['value'] = $form_state['values']['city'];
$story_form_state['values']['body'] = $form_state['values']['body'];
$story_form_state['values']['field_story_image'][0]['value'] = $form_state['values']['field_node_gallery_image'];
$story_form_state['values']['op'] = t('Save');
drupal_execute('story_node_form', $story_form_state, (object)$node);
}
Thank you for any help!
Maybe you need to add the node object to the form state?
From http://drupal.org/node/293663
Thank you again for all your
Thank you again for all your help. Unfortunatly that didn't fix the problem.
It actually seems like a validation issue. If I remove the required setting from the field and submit the form without an image it works perfectly.
Am I referencing the submitted form elements correctly for the image field?
2 things
First, unless you named your imagefield 'node_gallery_image' (which is what I named mine in the module), then you have the wrong value in there. I'm going to assume you called it 'story_image'.
Second, your arrays are out of alignment.
Give this a try:
$story_form_state['values']['field_story_image'] = $form_state['values']['field_story_image'];
Problem handing a CCK filefield in my form
Hi:
I need to do something very similar...add a file upload field to my form. I don't quite understand your code...can you please post your code for your content_fields and content_field_form functions?
My current problem is that I have a file upload field in my form, defined like so:
function mmil_upload_form ( $form_state )
{
....
$form['#attributes']['enctype'] = 'multipart/form-data';
$form['file'] = array (
'#type' => 'file',
'#description' => 'We accept .zip, .gzip, .tgz, tar.gz and .bz2 files up to 2 MB.',
'#required' => TRUE,
'#title' => t ( 'Choose your file to upload' ) );
$form['submit'] = array ( '#type' => 'submit', '#value' => 'Submit' );
return ( $form );
}
But when I choose a file to upload and then then click on the submit button, I get an error saying that "Choose your file to upload field is required.", so it thinks the file is missing. I don't understand why and what I can do to fix this problem.
Your help is appreciated.
Mona
filefield problem solved
I solved my problem...it turns out that I CANNOT use '#required' => TRUE when setting up the file field in the form! That field will be empty for both validate and submit. Instead I had to actually save the file in the submit function with file_save_upload() to valiidate it. Here is my submit function excerpt:
function a_upload_form_submit ( $form, &$form_state )
{
global $user;
$limits = _upload_file_limits ( $user );
$validators = array (
'file_validate_extensions' => array ( $limits['extensions'] ),
);
$file = file_save_upload ( 'file', $validators, null, false );
if ( $file == 0 )
{
form_set_error ( '', t ( 'Error: missing required upload file.' ) );
return;
}
// save data code here
}
Hope this helps someone else.
cheers,
Mona
Thanks
Thanks Justin.
FileField
I`m trying to create a CCK widget, based on FileField widget like that. Then I create new CCK widget for my content type. But I did not get this widget while creating a node.
<?php
// $Id:
/**
* Implementation of CCK's hook_widget_info().
*/
function filewidget_widget_info() {
return array(
'filewidget' => array(
'label' => t('Filewidget'),
'field types' => array('filefield'),
'multiple values' => CONTENT_HANDLE_CORE,
'callbacks' => array(
'default value' => CONTENT_CALLBACK_DEFAULT,
),
),
);
}
/**
* Implementation of CCK's hook_widget_settings().
*/
function filewidget_widget_settings($op, $widget) {
switch ($op) {
case 'form':
return filewidget_widget_settings_form($widget);
case 'validate':
return filewidget_widget_settings_validate($widget);
case 'save':
return filewidget_widget_settings_save($widget);
}
}
function filewidget_widget_settings_form($widget) {
$form = module_invoke('filefield', 'widget_settings', 'form', $widget);
if ($form['file_extensions']['#default_value'] == 'txt') {
$form['file_extensions']['#default_value'] = '3gp avi flv mp4 mpg mpeg';
}
$form['text'] = array(
'#type' => 'textfield',
'#title' => t('Text'),
'#default_value' => !empty($widget['text']) ? $widget['text'] : '',
'#size' => 15,
'#maxlength' => 10,
'#description' => t('Lorem ipsum dolorum set amen.'),
);
return $form;
}
function filewidget_widget_settings_validate($widget) {
}
function filewidget_widget_settings_save($widget) {
$filefield_settings = module_invoke('filefield', 'widget_settings', 'save', $widget);
return array_merge($filefield_settings, array('text'));
}
/**
* Implementation of CCK's hook_widget().
*
* Assign default properties to item and delegate to FileField.
*/
function filewidget_widget(&$form, &$form_state, $field, $items, $delta = 0) {
$element = filefield_widget($form, $form_state, $field, $items, $delta);
return $element;
}
/**
* Element #value_callback function.
*/
function filewidget_widget_value($element, $edit = FALSE) {
$item = filefield_widget_value($element, $edit);
return $item;
}
/**
* Element #process callback function.
*/
function filewidget_widget_process($element, $edit, &$form_state, $form) {
$element = array();
return $element;
}
/**
* Implementation of CCK's hook_default_value().
*/
function filewidget_default_value(&$form, &$form_state, $field, $delta) {
return filefield_default_value($form, $form_state, $field, $delta);
}
?>
Post new comment