8

I have a situation where I would like to be able to create nodes and referenced nodes at the same time. Are there any solutions for this that work well for this?

To clarify what I am talking about, consider the following situation (highly simplified for the sake of explanation):

There is a content-type Class that has a node referenced field, Student. I would like to have users be able to create Class nodes and Student nodes at the same time. I would also like them to be able to use the normal node reference auto-complete to pick a Student who happens to already exist.

Ideally, I would like all of this to work from a single page, and also work within the confines of the Drupal permission system so I can have various roles and various permissions.

Yes, I know that in this case Student would be best served as a user (rather than a node), but Class and Student are just to illustrate the situation. The real scenario really does need node references.

There is a similar question to this, Creating referenced nodes together with parent node, but I am specifically interested in Drupal 7 solutions only.

EDIT:

Not just looking for existing modules, but also head starts for custom code.

3
  • In Drupal 7, I've written some custom code to do this for my sites, simply because there are no module-based solutions yet that I can think of. You can even throw a form for creating the student node into a ctools modal, then pass back the nid to the original node form using ajax_command_data() or another ajax-data-passing function. Mar 30, 2012 at 18:41
  • @geerlingguy, if you write that up as an answer (esp a head start for the AJAX module nid passback), it would be seriously considered as an answer.
    – mpdonadio
    Mar 30, 2012 at 19:14
  • Will do in a little bit. Apr 1, 2012 at 2:37

5 Answers 5

4

I use References dialog, which puts a small "+" on existing reference fields allowing the user to create a new student directly from the class node edit form.

2
  • Has anyone used this module? I'd love to hear some feedback on the alpha releases. Sep 11, 2012 at 22:57
  • FYI Just installed this module and it seems to fit perfectly. Sep 12, 2012 at 0:46
8
+200

For a couple different sites now, I've done this using a ctools modal, and here's the basic outline of how I've implemented it (very simply):

  • Create a custom page callback in your module's hook_menu() that displays a basic node form for the node you want to reference (for a 'student' node, just have a name field and maybe a graduating year field). On that form, in your submit callback, save the node using node_save(), and store the node ID (which should be at $node->nid after you pass a new node object to node_save()) in the form's $form_state['storage']['student_id'].

  • Alter the master/Class node form using hook_form_alter(). You need to do a few things here:

First, you need to add in the ctools modal javascript and functionality so ctools knows what to do with your special link:

// Add in ctools modal js and functionality.
ctools_include('modal');
ctools_modal_add_js();

Second, you need to add a link to the page callback you created in step 1 in hook menu, and with that link, add the class 'ctools-use-modal'. So, for example:

// Add link to custom student form callback with ctools modal.
$form['add_student_link'] = array(
  '#markup' => l(t('Add Student'), 'mymodule/add-student', array('attributes' => array('class' => array('ctools-use-modal')))
);
  • In your custom page callback, you need to do a few things to make it work with or without JavaScript, and with ctools' form functions.

Here's an example callback:

<?php
function mymodule_student_form_callback($js = FALSE) {
  // Make sure $js (set by ctools) is TRUE/loaded.
  if ($js) {
    // Add in ctools modal form stuff.
    ctools_include('modal');
    ctools_include('ajax');
    $form_state = array(
      'ajax' => TRUE,
      'title' => t('Create a Student'),
    );

    $output = ctools_modal_form_wrapper('mymodule_create_student_form', $form_state);
  }
  else {
    return 'Javascript must be enabled for this feature to work.';
    // Or, if we wanted to load the form normally...
    // return drupal_get_form('mymodule_create_student_form');
  }

  // If the form is executed, dismiss the form and reload the page.
  if ($form_state['executed']) {      
    $commands = array();

    // Close the frame.
    $commands[] = ctools_modal_command_dismiss();

    // Use one of the ajax framework commands to place the returned
    // student node nid into the proper form value, placholder div, etc.
    // See: http://api.drupal.org/api/drupal/includes%21ajax.inc/group/ajax_commands/7
    $commands[] = ajax_command_append('#student-id-placeholder', $form_state['storage']['student_id']);

    $output = $commands;
  }

  // Render the output.
  print ajax_render($output);
  exit();
}
?>
  • In mymodule_create_student_form($form, $form_state), build your form like you normally would, and then in the mymodule_create_student_form_submit(form, &$form_state) (submit) function, set the value of the NID of the newly created student node in $form_state['storage']['student_id']. This is how you'll get ctools/AJAX to pass back the new nid to your original Class form.

  • In my situation, I was using the modal to spit back some markup to the original page, so I passed the markup into a placeholder div using ajax_command_append(), then I had some jQuery on the original page monitoring the placeholder div, and when it found content in it, it would move the HTML into the proper place elsewhere on the node form. In your case, you'll need to populate a single or multi-value node reference field, which may be a little more complex. I haven't needed to do that yet... so I don't have more advice to offer for that part of the equation.

4

An option might be to add node support to the Inline Entity Form module.

EDIT: Inline Entity Form has node support nowadays.

2

Following modules can be used in Drupal 7:

  1. https://drupal.org/project/noderefcreate
  2. https://drupal.org/project/nodeconnect
  3. https://drupal.org/project/entityconnect
  4. https://drupal.org/project/inline_entity_form

Noderefcreate only create new node if it does not exist by using autocomplete wizard. Nodeconnect and entityconnect provide add/edit button at node reference, if autocomplete wizard is used. Nodeconnect only provide it for node reference whereas entityconnect provide it for node reference, entity reference, term reference and user reference.

Inline_entity_form provides two extra widget for entity reference (only).

0

If this is really similar to the School scenario and your Students can join multiple Classes I would use:

  • 3 content types: Student (*-1) Attendance (1-*) Class
  • Form Block to enter Student data directly in a block;
  • Views Field to display a view with a list of Students attending a Class;

This would also require using Token, filtering the view depending on the Class nid and setting up a default value for the Attendance node reference field as the current Class nid.

Eventually you could map your Student content type to User with a user reference.

1
  • My content types already exist and the site works. Adding an intermediate type would require a lot of rework.
    – mpdonadio
    Apr 2, 2012 at 16:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.