Hi,

i am trying to open node edit form in modal window. here is the code i am using

function test_menu() {
  $items['test'] = array(
      'title' => 'Test Modal',
      'page callback' => 'test_page',
      'access callback' => TRUE,
      'type' => MENU_NORMAL_ITEM,
  );
  $items['test/%ctools_js/test'] = array(
      'title' => 'Test Content Type',
      'page callback' => 'modal_content',
      'page arguments' => array(1),
      'access callback' => TRUE,
      'type' => MENU_CALLBACK,
  );

  return $items;
}

function test_page() {
  global $user;

  ctools_include('ajax');
  ctools_include('modal');

  ctools_modal_add_js();

  $output = ctools_modal_text_button(t('Modal Content'), 'test/nojs/call', 'test');

  return array('markup' => array('#markup' => $output));
}


function modal_content($js = FALSE) {
  
  ctools_include('node.pages', 'node', '');
  
  if (!$js) {
    return drupal_get_form('test_node_form');
  }

  ctools_include('modal');
  ctools_include('ajax');
  $form_state = array(
    'title' => t('Add Notification'),
    'ajax' => TRUE,
  );
  $output = ctools_modal_form_wrapper('test_node_form', $form_state);
  if (!empty($form_state['executed'])) {
    
  }
  print ajax_render($output);
  exit;
}

i get the error "Fatal error: Cannot access empty property in field.attach.inc on line 197"

Comments

Letharion’s picture

Status: Active » Postponed (maintainer needs more info)

Can you try and reduce the code base a bit and determine which line causes the error message?
That will make it much easier for the maintainer to help you.

Deepakml’s picture

Thanks Letharion,

i think i found what the problem was, to load a content type we need to pass $form_state['build_info']['args'] in ctools_modal_form_wrapper(it calls drupal_build_form) and in drupal_get_form() pass it as 2nd argument. i made the following changes and it is working for me now.

$node = (object) array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => LANGUAGE_NONE);
drupal_get_form($type . '_node_form', $node);
$form_state['build_info']['args'] = array($node);
Letharion’s picture

Status: Postponed (maintainer needs more info) » Fixed

I'm glad you got it working :)

Status: Fixed » Closed (fixed)

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

netentropy’s picture

Was this for Drupa 7? Would you mind sharing what finally worked?

Deepakml’s picture

yes i am using d7.

add

$type = 'content type';
$node = (object) array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => LANGUAGE_NONE);
drupal_get_form($type . '_node_form', $node);
$form_state['build_info']['args'] = array($node);

after

$form_state = array(
    'title' => t('title'),
    'ajax' => TRUE,
  );

hope that works

Deepak

netentropy’s picture

Thanks for responding. For some reason it isn't working , it just does the ajax loading spin thing. I will keep working on it.

netentropy’s picture

I have tried mimicking your code. Can you see anything out of place?

function test_menu() {
  $items['test'] = array(
      'title' => 'Test Modal',
      'page callback' => 'test_page',
      'access callback' => TRUE,
      'type' => MENU_NORMAL_ITEM,
  );
  $items['test/%ctools_js/test'] = array(
      'title' => 'Test Content Type',
      'page callback' => 'modal_content',
      'page arguments' => array(1),
      'access callback' => TRUE,
      'type' => MENU_CALLBACK,
  );

  return $items;
}

function test_page() {
  global $user;

  ctools_include('ajax');
  ctools_include('modal');

  ctools_modal_add_js();

  $output = ctools_modal_text_button(t('Modal Content'), 'test/nojs/call', 'test');

  return array('markup' => array('#markup' => $output));
}


function modal_content($js = FALSE) {
  
  ctools_include('node.pages', 'node', '');
  
  if (!$js) {
    return drupal_get_form('test_node_form');
  }

  ctools_include('modal');
  ctools_include('ajax');
  $form_state = array(
    'title' => t('Add Notification'),
    'ajax' => TRUE,
  );
  $type = 'test';
$node = (object) array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => LANGUAGE_NONE);

drupal_get_form($type . '_node_form', $node);

$form_state['build_info']['args'] = array($node);

  $output = ctools_modal_form_wrapper('test_node_form', $form_state);
  
  if (!empty($form_state['executed'])) {
    
  }
  print ajax_render($output);
  exit;
}

netentropy’s picture

I finally got this nearly working. However submitting the form does not save the node. It does for you? New code:

 /**
 * A modal login callback.
 */
function modaltest_boom($js = NULL) {

  $type= 'test';
  //module_load_include('inc', 'node', 'node.pages');
  ctools_include('node.pages', 'node', '');
  
  if (!$js) {
    return drupal_get_form('test_node_form');
  }

  ctools_include('modal');
  ctools_include('ajax');
  $form_state = array(
    'title' => t('Add Notification'),
    'ajax' => TRUE,
  );
  $node = (object) array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => LANGUAGE_NONE);
  
drupal_get_form($type . '_node_form', $node);

$form_state['build_info']['args'] = array($node);

  $output = ctools_modal_form_wrapper('test_node_form', $form_state);
  
  if (!empty($form_state['executed'])) {
    
  };
  print ajax_render($output);
  exit;
}
APolitsin’s picture

***

APolitsin’s picture

  global $user;
  
  ctools_include('node.pages', 'node', '');
  ctools_include('modal');
  ctools_include('ajax');
  
  $type = 'test';
  $node = (object) array(
    'uid' => $user->uid, 
    'name' => (isset($user->name) ? $user->name : ''), 
    'type' => $type, 
    'language' => LANGUAGE_NONE);
     
  if (!$js) {
    return drupal_get_form($type . '_node_form', $node); /** You miss _$node_ here */
  }

  $form_state = array(
    'title' => t('Add Test page'),
    'ajax' => TRUE,
  );
  
  /** drupal_get_form($type . '_node_form', $node);  // And remove this code */

  $form_state['build_info']['args'] = array($node);

  $output = ctools_modal_form_wrapper($type . '_node_form', $form_state);
  
  if (!empty($form_state['executed'])) {
    $output = array();
    $output[] = ctools_modal_command_display(
      t('Node created'), 
      '<div class="modal-message">Node creation successful.</div>'); /** Add success message*/
  }
  print ajax_render($output);
  exit;  
marcel66’s picture

Status: Active » Closed (fixed)

Hello all

I have figured out that your code works well (except of some urls: in hook_menu is mentioned 'test/%ctools_js/test' and in link 'test/nojs/call' - they have to be the same.)

BUT... when you have a test node with an image field... and you want to load a new image ... you'll get an error... => ajax problems with form with ajax fields <-> ctools

marcel66’s picture

Status: Closed (fixed) » Active
mkadin’s picture

Status: Closed (fixed) » Active

Confirmed #12, using the image field on the standard "article" node/add form works if you just hit save without uploading first. But if you use the AJAX "upload" button, you get the following error below. Hitting save brings the form up again, this time with the image thumbnail showing - the image has been successfully uploaded. Hitting save again actually saves the form.

Here's the error:

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 785 of /Applications/MAMP/htdocs/drupal-7.10/includes/form.inc).
Notice: Undefined index: #node in comment_form_node_form_alter() (line 1193 of /Applications/MAMP/htdocs/drupal-7.10/modules/comment/comment.module).
Notice: Trying to get property of non-object in comment_form_node_form_alter() (line 1210 of /Applications/MAMP/htdocs/drupal-7.10/modules/comment/comment.module).
Notice: Undefined index: #node in menu_form_node_form_alter() (line 612 of /Applications/MAMP/htdocs/drupal-7.10/modules/menu/menu.module).
Notice: Trying to get property of non-object in menu_form_node_form_alter() (line 612 of /Applications/MAMP/htdocs/drupal-7.10/modules/menu/menu.module).
Notice: Undefined index: #node in menu_form_node_form_alter() (line 613 of /Applications/MAMP/htdocs/drupal-7.10/modules/menu/menu.module).
Notice: Trying to get property of non-object in menu_form_node_form_alter() (line 613 of /Applications/MAMP/htdocs/drupal-7.10/modules/menu/menu.module).
Notice: Undefined index: #node in auto_nodetitle_form_node_form_alter() (line 29 of /Applications/MAMP/htdocs/drupal-7.10/sites/all/modules/auto_nodetitle/auto_nodetitle.module).
Notice: Trying to get property of non-object in auto_nodetitle_form_node_form_alter() (line 29 of /Applications/MAMP/htdocs/drupal-7.10/sites/all/modules/auto_nodetitle/auto_nodetitle.module).
Notice: Undefined index: #node in auto_nodetitle_form_node_form_alter() (line 36 of /Applications/MAMP/htdocs/drupal-7.10/sites/all/modules/auto_nodetitle/auto_nodetitle.module).
Notice: Trying to get property of non-object in auto_nodetitle_form_node_form_alter() (line 36 of /Applications/MAMP/htdocs/drupal-7.10/sites/all/modules/auto_nodetitle/auto_nodetitle.module).
Notice: Undefined index: field_image in file_ajax_upload() (line 267 of /Applications/MAMP/htdocs/drupal-7.10/modules/file/file.module).
Notice: Undefined index: #suffix in file_ajax_upload() (line 276 of /Applications/MAMP/htdocs/drupal-7.10/modules/file/file.module).

thetoast’s picture

I've come across the same error as above, trying to figure out how it could be fixed because hitting the upload button causes the form to submit which is when the error occurs. My entity reference auto complete fields don't work in ctools modal either but I don't get any errors, basically it looks like anything that uses ajax isn't working. Also, I've noticed if you use jquery ui dialog (in drupal 7 core) you can display a node add page (calling node/add/*) which means you're not calling the node form directly which ultimately means ajax widget fields work fine. Dialog api seems to suffer from the same issue with image uploads, see here

eO_Ae’s picture

I am getting this error, but only on my production environment.

Everything is working fine locally. Its some sort of environmental difference, but I don't even have a clue what its getting hung up on.

nagiek’s picture

Make sure you include all the JS in your form by calling

  $form_state['build_info']['base_form_id'] = 'node_form';
  drupal_prepare_form($node_type . '_node_form', $form, $form_state);
bachbach’s picture

hi, thanks for these samples!

i'm trying to replicate this, but i can't make it work.
i always have php memory errors

[Sat Mar 10 23:54:59 2012] [error] [client 127.0.0.1] PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 40961 bytes) in /users/bachir/Sites/domain.org/includes/theme.inc on line 1400, referer: http://dev.domain.org/en/node/454/edit?destination=admin/content/nodes

always with theme.inc on line 1400
as far as i was able to go, it's happend on $output = drupal_render($output); L226 ctools_modal_form_render() of modal.inc

my code is exactly #11

function tode_entity_add_form($bundle, $entity, $js = FALSE) {
	// dsm('- - - - tode_entity_add_form');
	//   dsm($bundle, '$bundle');
	//   dsm($entity, '$entity');
	$type= $entity;
		
	global $user;

	//module_load_include('inc', 'node', 'node.pages');
	ctools_include('node.pages', 'node', '');

	$node = (object) array(
		'uid' => $user->uid, 
		'name' => (isset($user->name) ? $user->name : ''), 
		'type' => $type, 
		'language' => LANGUAGE_NONE
	);

	if (!$js) {
		return drupal_get_form($type.'_node_form');
	}

	ctools_include('modal');
	ctools_include('ajax');
	
	$form_state = array(
		'title' => t('Add '.$entity),
		'ajax' => TRUE,
	);
	
	$form_state['build_info']['args'] = array($node);

	$output = ctools_modal_form_wrapper($type.'_node_form', $form_state);
	
	if (!empty($form_state['executed'])) {
	   $output = array();
	    $output[] = ctools_modal_command_display(
	      t('Node created'), 
	      '<div class="modal-message">Node creation successful.</div>'); /** Add success message*/
	};

	print ajax_render($output);
	exit;
}

i tried with a minimum test node type (only title field), it's the same
i'm working localy with 256M php memory

drupal 7.12
ctools 7.x-1.0-rc1

any clue ?

bachbach’s picture

process go through this line

if (isset($elements['#theme'])) {
  $elements['#children'] = theme($elements['#theme'], $elements);
}

L5727 from /includes/common.inc

as info, i'm trying to open a node create form in ctools modale from an other node edit form … maybe some recursions here ?

bachbach’s picture

OK got it !
this is some incompatibilty with Node form columns module, if i disable it, all works fine
opened an issue here : http://drupal.org/node/1479264
i will check that !

arisaves’s picture

Where does one place the code in #11?

nguyentran’s picture

Hello bachbach,

I can not solve the 200 error, have you solved this, please help. Thanks

jamuy’s picture

bachbach, en tu codigo #18

Fiajte que no inlcuyes el fomulario si es

drupal_get_form($type . '_node_form', $node);

$form_state['build_info']['args'] = array($node);

jurveen’s picture

+1

I'll tried all the above code for a node add/edit form, unfortunately with no success. It results in a 200 error and a dump of the form array.
Also tried this code here: https://gist.github.com/1979037 See the code below. Same result.

I use Drupal 7.14, CTools 1.0.

I keep on trying to find a solution. Any suggestions?


function mymodule_menu() {
  $items = array(); 

  $items['mymodule/%ctools_js/mytype/edit'] = array(
    'title' => 'Edit mytype',
    'description' => 'Edit mytype.',
    'page callback' => 'mymodule_edit_modal_mytype',
    'page arguments' => array(1),
    'weight' => 2,
    'access arguments' => array('administer mymodule'),
    'type' => MENU_CALLBACK,
  );
  
  return $items;
}


function mymodule_edit_modal_mytype($js = FALSE) {
  global $user;

  if (!$js) return "Javascript required";
  
  ctools_include('node.pages', 'node', '');
  ctools_include('modal');
  ctools_include('ajax');

  // Example node of type mytype.
  $node = node_load(1);

  $form_state = array(
    'title' => t('Edit my content type'),
    'ajax' => TRUE,
  );

  $form_state['build_info']['args'] = array($node);
  // change this to your type node form
  $output = ctools_modal_form_wrapper('mytype_node_form', $form_state);

  // This means the form has been exectued
  if (!empty($form_state['executed'])) {
    $output = array();
    // Close the modal
    $output[] = ctools_modal_command_dismiss();
  }
  
  print ajax_render($output);
  exit;
}


// Alter the myothertype form, add 1 or more modal links.
function mymodule_form_myothertype_node_form_alter(&$form, &$form_state, $form_id) {
  // Include the CTools tools that we need.
  ctools_include('ajax');
  ctools_include('modal');

  // Add CTools' javascript to the page.
  ctools_modal_add_js();

  // Some sample code from a ctools example. You can create a list of modal links.
  // Right now, we use only 1 link.
  $links = array();
  $links[] = ctools_modal_text_button(t('Edit mytype item (default modal)'), 'mymodule/ajax/mytype/edit', t('Edit mytype'));
  $output = theme('item_list', array('items' => $links, 'title' => t('Actions')));
  $form["myfield"]['#markup'] = $output;
}

mkadin’s picture

@jurveen Try adding this line anywhere inside your form alter:

form_load_include($form_state, 'inc', 'node', 'node.pages');
jurveen’s picture

Hi mkadin, thanks for your suggestion. No luck so far.
Isn't ctools_include('node.pages', 'node', ''); supposed to do the same?

jurveen’s picture

Okay, I got it working! Now, the modal shows the node form with either ctools_include('node.pages', 'node', '') or form_load_include($form_state, 'inc', 'node', 'node.pages').

It seems that the error came from the content type itself. I recreated the content type with exactly the same fields, and now it's working fine. I flushed all caches etc. etc. When I use ctools_modal_form_wrapper() with the old content type, the error reappears! Did anyone have similar experiences, or am I just going crazy?? :(

jernej.c’s picture

Sorry guys, this is a stupid question, but I'm brand new to Drupal. What do I do with the code above? :o

Thanks for any kinda help in advance.

Jernej

jernej.c’s picture

Ok, I created a module and enabled it ( I hope this is meant to be a module :P ), but what now? How do I add the links?

drupaledmonk’s picture

Has anyone been able to fix #14

mkadin’s picture

@drupaledmonk, I believe I was able to solve that problem by adding

module_load_include('inc', 'node', 'node.pages');

In the modal callback

and/or by adding

form_load_include($form_state, 'inc', 'node', 'node.pages');

In a form alter for the form in the modal.

havran’s picture

I work with code from #11 but i get AJAX error dump. If i comment out this part

  if (!$js) {
    return drupal_get_form($type . '_node_form', $node); /** You miss _$node_ here */
  }

whole node creation process work as expected (form show modal, submit work and node is saved). I debug $js value and i get 0.

havran’s picture

My fault. I use in url 'no_js' and there need to by 'nojs'! This is replaced by 'ajax' in post... Now all working correctly. Here is complete solution for all existing node types (node/add and node/%/edit) http://drupal.stackexchange.com/a/45150/10664.

ashish.verma85’s picture

tarasikarius’s picture

Hi guys. I added node ADD form in ctools modal window and ctools autosubmit functionality .
So far so good, but my goal is to return node EDIT form when autosubmit triggered.
Now modal callback function looks like this:

function my_module_node_add_modal_callback($js = FALSE) {
  global $user;
  if (!$js) {
    return "Javascript required";
  }

  ctools_include('node.pages', 'node', '');
  ctools_include('modal');
  ctools_include('ajax');
  ctools_add_js('auto-submit');

  // Create a blank node object.
  $node = (object) array(
    'uid' => $user->uid,
    'name' => (isset($user->name) ? $user->name : ''),
    'type' => 'node_type',
    'language' => LANGUAGE_NONE,
    );

  $form_state = array(
    'title' => t('Add node'),
    'ajax' => TRUE,
  );

  $form_state['build_info']['args'] = array($node);
  $output = ctools_modal_form_wrapper('node_type_node_form', $form_state);

  
  if (!empty($form_state['executed'])) {
   
  }

  print ajax_render($output);
  exit;
}

I tryed to add different varians of this:

if (!empty($form_state['executed'])) {
    $output = array();

    if ($form_state['nid']) {
      $node = node_load($form_state['nid']);

       $form_state = array(
          'title' => t('Add node'),
          'ajax' => TRUE,
        );

       $form_state['build_info']['args'] = array($node);
       $output = ctools_modal_form_wrapper('node_type_node_form', $form_state);
    }
  }

but it doesn`t work(

Any advice?

shobhit_juyal’s picture

#11 Perfect thanks.

m.attar’s picture

MustangGB’s picture

Status: Active » Closed (outdated)