Developers often want to embed a node form. So I'll try to work out, how this is done best in drupal 6. For 5.x I provided the subform element module, which was an easy way to do it. However recently I found out, that embedding fully working node forms in 6.x isn't so easy any more. The funky JS stuff of node forms, which relies on the #ahah form API property, fails if $form doesn't look that way it expects.
I've put this all together in a small example module, which can be found in my sandbox.
So how to embed a node form with working AHAH?
Fortunately, it's not that hard either. We must just ensure to keep the structure of $form as in the original form. So don't move the embedded form in $form['fieldgroup'] - or it's #ahah stuff gonna break. So let's show how to embed a node creation form. First off we have to get the form array of the node form: $user->uid, 'name' => $user->name, 'type' => $type); $form = drupal_retrieve_form($type .'_node_form', $form_state, $node); drupal_prepare_form($type .'_node_form', $form, $form_state); ?> Now we have the form array, already altered by hook_form_alter() implementations. We could just go and use it - even its validation and submit handlers would be invoked. But we face two problems:How to add own elements at the top and the bottom of the form?
That's not really hard. We have to add our #theme function that renders our own elements first and inserts the rendered, embedded form in the middle. Furthermore we make sure that the embedded form looks right by applying it's theme function. So we add our own #theme function and save the #theme property of the embedded form for later: Then we make sure the embedded form is themed too:How to keep control over the form?
If the form comes with it's own validation, submit handlers and different buttons with different handlers it can be quite cumbersome to make sure that a own handler gets executed. So one can use a #after_build callback to just add the own handlers after the form API has determined the handlers, which are to be invoked. When the #after_build callback gets executed, all button presses have been already detected, apart from a special case which fixes submitting single button forms for IE users. Usually this is not the case for node forms, but this code deals with this case too: That's it.I've put this all together in a small example module, which can be found in my sandbox.
silly me!
the example is in the subform module!
Add new comment | Wolfgang Ziegler // fago
Your knowledge connecting with theme would be used by paper writing services as the
examples for the dracula discussion questions accomlplishing.
Stop by my website - dracula discussion questions
First argument is expected to be a valid callback
When calling
$form = drupal_retrieve_form($type .'_node_form', $form_state, $node);
with a type set to match the name of my CCK type $type = 'productregistration';
I keep getting the error:
warning: call_user_func_array() [function.call-user-func-array]: First argument is expected to be a valid callback, 'node_form' was given in /var/www/html/drupal-6/includes/form.inc on line 366.
This is the start of the tutorial - so don't think i can have missed anything out previous to this call in my code. Any ideas?will this work for existing nodes?
Should this technique be able to pull in the edit form of an EXISTING node?
Rather than the $node init you have above i do this:
$nrnode = node_load(896525);
$nrform = drupal_retrieve_form($nrnode->type .'_node_form', $nrform_state, $nrnode);
drupal_prepare_form($nrnode->type .'_node_form', $nrform, $nrform_state);
at the end, $nrform is a form array but $form['nid'], etc are NULL and there are also none of the CCK fields included.
Peter Lindstrom
www.LiquidCMC.canot CCK aware
so i tried your example module and replaced:
$node = array('uid' => $user->uid, 'name' => $user->name, 'type' => $type);
wiith:
$node = node_load(53383);
and sure enough it is picking up the nid for the use in newly created form and does display title/body of $node - but doesn't include any of the CCK fields.
post issues
site seems to have lost my first post in this thread.. :(
www.LiquidCMC.ca
hmm.. and now works
not sure what i did; but this now seems to work...
this snippet actually "attaches" a cck node edit form of an existing node to an field in another node edit form.
the module this is in is weighted high so that the field groups have been established; then i am adding this to a field in a group.
$nrnode = node_load(53383);
$nrform_state = array();
$nrformid = $nrnode->type .'_node_form';
$nrform = drupal_retrieve_form($nrformid, $nrform_state, $nrnode);
drupal_prepare_form($nrformid, $nrform, $nrform_state);
$form['group_fsp']['field_pkg_fsp'][0]['_edit'] = $nrform;
still messes up some of the vertical tabs of my original form but possibly some trimming or cleanup of attached from array to help that.
<code>
hey fago,
reason my post content was lost was because i used the < code > tag... posts don't display if that is used
How to embed a node form into a page in Druapl 6
Basically this is what I used to do on Drupal 5.x:
<?php
print node_add('my_content_type');
?>
But on Drupal 6.x you need to put:
<?php
if( !function_exists("node_object_prepare")) {
include_once(drupal_get_path('module', 'node') . '/node.pages.inc');
}
print node_add('my_content_type');
?>
Another alternative:
<?php
global $user;
if( !function_exists("node_object_prepare")) {
include_once(drupal_get_path('module', 'node') . '/node.pages.inc');
}
$type = 'your content type';
// Initialize settings:
//research paper
$node = array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => '');
print drupal_get_form($type .'_node_form', $node);
?>
Counting arguments
I just started development with drupal and start hitting walls here and there. I tried to embed node forms into a multi step form created with the help of chaos tools as described here "http://www.nicklewis.org/using-chaos-tools-form-wizard-build-multistep-forms-drupal-6" which at the moment still fails.
So I dug into the code of "drupal_retrieve_form()" and its arguments and the first thing I don't get is why you pass along three arguments to a function that by definition only takes two ( "drupal_retrieve_form($form_id, &$form_state)" ).
Update:
Got it working. Yay! Just had to put some more items in the "$items"-array in the "'module-name'_menu"-function. Looks like I just get to know a few things I also should dig deeper into :)
Thx for your post.
Drupal 7
What should I use for Drupal 7?
subform module
For Drupal 7 try the subform module.
link for embed_example
Great approach. The link to your embed_example module seems to not point to the correct place anymore — can you provide an alternative.
Also, how are you printing out the embedded for in tpl.php files?
print drupal_render_form()
outputs a form missing cck fields and broken fieldsets.The CVS sandbox was not
The CVS sandbox was not converted during the great Git migration. I've just imported the files manually in a Git sandbox and fixed the link above.