3

I want to attach or embed a node form to a view so that when a user submits the form, the view below the form will be updated in realtime via ajax. The form will be shown above the view. My views block name is Statuses Stream.

I tried formblock module and putting the form in the header section of my view using views ui, but after submit, it was redirecting to the node created page.

Then I tried Advanced Form Block module. I created a form using AFB module. It is submitting the form with ajax, but it is not updating the view in the realtime.

I have just tried the Ajax Form Entity module. It is submitting and updating via ajax, but I cannot find a way to attach a view with it. However, in its settings, I can select a view mode. I need a little more flexibility.

How to Attach or embed node form to a view so that it submits via ajax and updates the view in realtime? I am open to any solution programmatically or through a module. Better if done programmatically because it will give more flexibility.

2
+50

I'ld take it from the other side: Attach a view to a node form.

First I tried it with the built-in node form. But this turned out to be quite a hassle. Instead I built a small custom form and created new nodes programmatically. Ajax submit. View refreshed. Happy, happy.

Here comes the code for a custom module. Presuming a fresh D7 standard installation.

Info file

name = MYMODULE
description = Provides cool stuff.
core = 7.x
package = Custom
dependencies[] = views

Module file

First provide a view.

/**
 * Implements hook_views_api().
 */
function MYMODULE_views_api() {

  return [
    'api' => 3,
  ];
}

/**
 * Implements hook_views_default_views().
 */
function MYMODULE_views_default_views() {

  $view = new view();
  $view->name = 'nodes';
  $view->description = '';
  $view->tag = 'default';
  $view->base_table = 'node';
  $view->human_name = 'Nodes';
  $view->core = 7;
  $view->api_version = '3.0';
  $view->disabled = FALSE;

  /* Display: Master */
  $handler = $view->new_display('default', 'Master', 'default');
  $handler->display->display_options['title'] = 'Nodes';
  $handler->display->display_options['use_more_always'] = FALSE;
  $handler->display->display_options['access']['type'] = 'none';
  $handler->display->display_options['cache']['type'] = 'none';
  $handler->display->display_options['query']['type'] = 'views_query';
  $handler->display->display_options['exposed_form']['type'] = 'basic';
  $handler->display->display_options['pager']['type'] = 'none';
  $handler->display->display_options['pager']['options']['offset'] = '0';
  $handler->display->display_options['style_plugin'] = 'default';
  $handler->display->display_options['row_plugin'] = 'fields';
  /* Field: Content: Title */
  $handler->display->display_options['fields']['title']['id'] = 'title';
  $handler->display->display_options['fields']['title']['table'] = 'node';
  $handler->display->display_options['fields']['title']['field'] = 'title';
  $handler->display->display_options['fields']['title']['label'] = '';
  $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
  $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
  /* Sort criterion: Content: Post date */
  $handler->display->display_options['sorts']['created']['id'] = 'created';
  $handler->display->display_options['sorts']['created']['table'] = 'node';
  $handler->display->display_options['sorts']['created']['field'] = 'created';
  $handler->display->display_options['sorts']['created']['order'] = 'DESC';

  /* Display: Block */
  $handler = $view->new_display('block', 'Block', 'block');

  $views[$view->name] = $view;
  return $views;
}

Then do the form.

/**
 * Provide a form.
 */
function MYMODULE_form($form, &$form_state) {

  $form['wrapper'] = [
    '#type'       => 'container',
    '#attributes' => [
      'id' => 'mywrapper',
    ],
  ];

  $form['wrapper']['node_form'] = [
    '#type'  => 'fieldset',
    '#title' => t('Add article'),
  ];

  $form['wrapper']['node_form']['node_title'] = [
    '#type'     => 'textfield',
    '#title'    => t('Article title'),
    '#required' => TRUE,
  ];

  $form['wrapper']['submit'] = [
    '#type'   => 'submit',
    '#value'  => t('Save'),
    '#submit' => ['MYMODULE_form_submit'],
    '#ajax'   => [
      'callback' => 'MYMODULE_MYCALLBACK',
      'wrapper'  => 'mywrapper',
    ],
  ];

  $form['wrapper']['view_display'] = [
    // view machine name && display/block name
    '#markup' => views_embed_view('nodes', 'block'),
  ];

  return $form;
}

/**
 * Do some validation.
 */
function MYMODULE_form_validate($form, &$form_state) {
  // Better do some validation.
  // Here or via #element_validate.
  // @see https://api.drupal.org/api/drupal/developer%21topics%21forms_api_reference.html/7.x#element_validate
}

/**
 * Form submit. Node creation.
 */
function MYMODULE_form_submit($form, &$form_state) {

  global $user;
  $node = new stdClass();

  $node->type     = 'article';
  $node->title    = $form_state['values']['node_title'];
  $node->language = LANGUAGE_NONE;
  $node->uid      = $user->uid;

  node_object_prepare($node);
  node_save($node);

  // Empty out title field on rebuild.
  $form_state['input']['node_title'] = '';

  // Rebuild form.
  $form_state['rebuild'] = TRUE;
}

/**
 * Ajax callback to return the whole wrapper.
 */
function MYMODULE_MYCALLBACK($form, &$form_state) {

  return $form['wrapper'];
}

I've put it on a sample page to see it in action.

/**
 * Implements hook_menu().
 */
function MYMODULE_menu() {

  $items['example/form'] = [
    'title'            => 'Example Form',
    'description'      => 'A form to mess around with.',
    'page callback'    => 'drupal_get_form',
    'page arguments'   => ['MYMODULE_form'],
    'access arguments' => ['create article content'],
  ];

  return $items;
}
  • I have few questions. 1. To change content type I just have to change here $node->type = 'article'; right? 2. In the view above, I do not see content type article. Why? 3. Will this form work as the node form does? I mean the settings in content type article will still have its effects? Like fields or enabling disabling text formats etc. 4. Regarding the 'id' => 'mywrapper' and 'wrapper' => 'mywrapper' Can I change it to anything? 5. What I am supposed to replace MYCALLBACK with here 'callback' => 'MYMODULE_MYCALLBACK', – Umair Jun 21 '17 at 19:07
  • 6. In hook menu, what I have understood, example/form is the url where users will see this whole thing. right? What if I do not want to show it on a page. Instead show it in a block which I can put anywhere on the website. – Umair Jun 21 '17 at 19:08
  • 7. How to hide the title? I do not want users to insert and see the title field – Umair Jun 21 '17 at 19:11
  • @Umair - You can render the form everywhere you want. In a block, in a template. As you need. The page is only for demo purpose. Then, please, post a separate question for every problem that persists. – leymannx Jun 21 '17 at 19:28
  • 1
    @Umair - The callback can be named anything you want. You could also simply leave it as it is now. – leymannx Jun 21 '17 at 19:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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