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;
}