Perform the following steps to reproduce the issue
1. Create block

/*
 * hook_block_info
 */
function mymodule_block_info() {
 		  $blocks[0] = array(
		    'info' => t('Node form in block'),
		     // Cached elsewhere.
		    'cache' => DRUPAL_NO_CACHE,
		  );
 return $blocks;
}
/*
 * hook_block_view
 */

function mymodule_block_view($delta = '') {
  module_load_include('inc','node','node.pages');

  $block['content'] = node_add('page');
  return $block;

}

2. Implement form alter and inject ajax element

/*
 * hook_form_FORM_ID_alter
 */
function mymodule_form_node_form_alter(&$form, &$form_state, $form_id){
	$node = $form['#node'];
	$type = $node->type;
//add the calculate button
         $form['actions']['btn_calculate']=array('#type'=>'button','#value'=>t('Compute'),
             '#ajax'=> array('callback' => 'mymodule_compute',
              'wrapper' => "div_output_$type",),
             '#weight'=>'49',
             );		
 //add the div to display output of calculation
 		 $form["replace_div_$type"] = array(
			'#markup'=>'',
		    '#prefix' => "<div style='clear:both;' id='div_output_$type'>",
		    '#suffix' => '</div>',
 		    '#weight'=>'50',
		  );
}
/*
 * implement mymodule_compute
 */
function mymodule_compute($form,&$form_state){ 
  $node = $form['#node'];
  $type = $node->type;
  $form["replace_div_$type"]['#markup']=t('Hello world');
  return  $form["replace_div_$type"];
}

3. Add the block to the content region
4. Click on the "Compute" button

The error "Call to undefined function node_form_validate" occurs.

Note: this problem does not occur when the menu node/add/page is called

Comments

rfay’s picture

subscribe

dawehner’s picture

What about creating a wrapper form which loads the node page.

The problem here is when you call ajax the form is build, but the block system is not used at all.

sukr_s’s picture

The current work around that i'm using is to load the node.pages.inc on the top level (outside all functions) in the module that defines this block. but i think there should be a better way to do that.

idflood’s picture

Thanks sukr_s, you saved me some time. I too think there should be better way.

by the way, I included this line at the top of my module:
require_once(DRUPAL_ROOT . "/modules/node/node.pages.inc");

inductor’s picture

Sukr_s, thanks for a workaround! The error happens also when you try to put the node add form (with ajax file/image upload widgets) into a block.

wizonesolutions’s picture

Subscribe - going to look into this if I get a chance.

Eric_A’s picture

Eric_A’s picture

Or don't use node_add() but call the form directly, after having done a form_load_include().

inductor’s picture

Unfortunately, form_load_include() doesn`t do the job:

/**
 * Implementation of hook_menu().
 */
function simple_node_menu() {
	$items['simple_node/new-post'] = array(
		'page callback' => 'drupal_get_form',		
		'page arguments' => array('simple_node_form'),
		'access callback' => 'user_access',
		'access arguments' => array('create post content'),
	);	
	return $items;
}

/**
 * Add new post form
 */
function simple_node_form($form, &$form_state) {
	global $user;  
	
	$node = (object) array(
		'uid' => $user->uid, 
		'name' => (isset($user->name) ? $user->name : ''), 
		'type' => 'post', 
		'language' => LANGUAGE_NONE,
	);
  
  $node_form = drupal_get_form('post_node_form', $node);
  form_load_include($form_state, 'inc', 'node', 'node.pages');
  
  return $node_form;
}

gives the:

Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'node_form' not found or invalid function name in drupal_retrieve_form() (line 771 of /var/www/d7/includes/form.inc).

error.
Maybe, I`m doing something wrong?

Eric_A’s picture

Category: bug » support

@inductor
You're working with a menu router page callback, two form ID's, mixing up their $form_states. (And to me it looks bizar to have a menu router item get a form and then within the form constructor get another form and return that one...)
This issue is really about making sure that a cached form knows what to include before the processing starts.

The basic idea is something like this:

$node = (object) array(
  'uid' => $user->uid, 
  'name' => (isset($user->name) ? $user->name : ''), 
  'type' => 'page', 
  'language' => LANGUAGE_NONE,
);
$form_state = array();
$form_state['build_info']['args'] = array($node);
form_load_include($form_state, 'inc', 'node', 'node.pages');
return drupal_build_form('page_node_form', $form_state);
inductor’s picture

Thanks, Eric_A, your solution in #10 works!

m4olivei’s picture

Solution in #10 works for me as well.

I also found the same issue as noted here when using node_page_edit() to render a node edit form. In my case I was using a multi-value node reference field (references module) with an auto-complete textfield, and was getting the error noted when adding fields.

In case anyone would like to see the replacement for a call to node_page_edit():

$type_name = node_type_get_name($node);
drupal_set_title(t('<em>Edit @type</em> @title', array('@type' => $type_name, '@title' => $node->title)), PASS_THROUGH);
    
// Render the form
$form_state = array();
$form_state['build_info']['args'] = array($node);
form_load_include($form_state, 'inc', 'node', 'node.pages');
return drupal_build_form($node->type . '_node_form', $form_state);

Thanks!

mdupont’s picture

Status: Active » Fixed

Seems like it's fixed.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

kurtzhong’s picture

This is a very interesting issue, #3 work good for me.
I am so unlucky, #10 doesn't work. I am invoking a node edit form, and when i upload image, if i click `upload`, then it will return `no file input`.

Eugene Fidelin’s picture

File uploads doesn't work through AJAX. User must first click "Upload" button and then click "Submit" - in this case when AJAX form is submitted file will be already uploaded previously - and you won't get this bug.

Try this solution if you want to upload files automatically after user selects them http://drupal.stackexchange.com/questions/31121/how-can-i-automatically-...

Anybody’s picture

This answer may help you and others:
http://julian.pustkuchen.com/node/702

gangu’s picture

Hello,

On drupal 7, I have a problem with a form. Render content type form in drupal 7 everthing working fine but

I created a Field Collection which appears in the node.

When I click Add another item this error occurs

/************Error************/
An AJAX HTTP request terminated abnormally.
Debugging information follows.
Path: /system/ajax
StatusText: n/a
ResponseText: ShareEmailFacebookTwitterGoogle+PinterestLinkedInStumbleUponRedditGoogle BookmarksWordPressTumblrDeliciousDiggMySpaceYahoo BookmarksBeboMister-WongApp.netWaneloOrkutXINGBufferEvernoteWhatsAppMendeleyPocketVKPinboardSpringpadFlipboardArtoAIMYahoo MessengerPlurkDiasporaBlogger PostTypePad PostBox.netKindle ItBaiduNetlogCiteULikeJumptagsFunPInstapaperPhoneFavsXerpiNetvouzDiigoBibSonomyBlogMarksStartAidKhabbrMeneameYoolinkBookmarks.frTechnotizieNewsVineFriendFeedProtopage BookmarksBlinklistYiGGWebnewsSegnaloPushaYouMobSlashdotFarkAllvoicesJamespotTwiddlaLinkaGoGoNowPublicLiveJournalLinkatopiaBuddyMarksViadeoWistsSiteJotDZoneCare2 NewsBitty BrowserOdnoklassnikiMail.RuSymbaloo FeedsFolkdNewsTrustAmazon Wish ListPrintFriendlyTuentiEmailRediff MyPageGoogle GmailYahoo MailOutlook.comAOL MailAny email    By AddToAny
We Are Working On Riley Drupal
The website encountered an unexpected error. Please try again later.

ReadyState: undefined
/***********************/
function customurl_menu() {
$items = array();
$items['program/%/register'] = array(
'title' => t('Add @node_type', array('@node_type' => t('Node Type'))),
'page callback' => 'drupal_get_form',
'page arguments' => array('module_node_add_form', 'registration'),
'access arguments' => array('administer nodes'),
'file path' => drupal_get_path('module', 'node'),
'file' => 'node.pages.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
return $items;
}

function module_node_add_form ($form, &$form_state, $node_type) {
global $user;
//if( !function_exists("node_form")) {
module_load_include('inc', 'node', 'node.pages');
//}
//if( !function_exists("field_collection_item_form_validate")) {
module_load_include('inc', 'field_collection', 'field_collection.pages');
// }
$node = (object) array(
'uid' => $user->uid,
'name' => (isset($user->name) ? $user->name : ''),
'type' => $node_type,
'language' => LANGUAGE_NONE,
);

node_object_prepare($node);
$form_state['build_info']['args'] = array($node);
form_load_include($form_state, 'inc', 'node', 'node.pages');
$form = drupal_retrieve_form($node_type . '_node_form', $form_state);
drupal_prepare_form($node_type . '_node_form', $form, $form_state);
return $form;

}

ramkris’s picture

Hi,

Please check the below link
https://www.drupal.org/forum/support/post-installation/2013-01-23/call-t...

if(!isset($form_state['build_info']['files'])){
$form_state['build_info']['files'] = array("menu" => "modules/node/node.pages.inc");
}

this solution working fine for me.