一页上有drupal多节点表单

时间:2009-11-10 22:03:55

标签: api drupal forms

我有一个显示多个节点的视图。我想在每个显示的节点下面放置节点表单。直接在template.php中的node_adddrupal_get_form都可以正常工作,但我会获得具有相同表单ID NODETYPE_node_form的表单,并且验证和提交无法按预期工作。

如果您必须在一个页面上放置几个节点表单,那么您的一般方法是什么?

到目前为止的进展......

预处理节点时,在template.php中

$ author_profile和$ content之前设置。

$unique = $vars['node']->nid;

$node = new StdClass();
$node->uid = $vars['user']->uid;
$node->name = $vars['user']->name;
$node->type = 'review';
$node->language = '';
$node->title = t('Review of ') . $vars['node']->realname . t(' by ') . $vars['user']->realname . t(' on ') . $content->title;
$node->field_review_to_A[0]['nid'] = $nodeA->nid;
$node->field_review_to_B[0]['nid'] = $vars['node']->nid;
$node->field_review_to_profile[0]['nid'] = $author_profile->nid;

if(!function_exists("node_object_prepare")) {
    include_once(drupal_get_path('module', 'node') . '/node.pages.inc');
}

//$vars['A_review_form'] = drupal_get_form('review_node_form', $node);
$vars['A_review_form'] = mymodule_view($node, $unique);
mymodule模块中的

function mymodule_view($node, $unique) {
    if(!function_exists("node_object_prepare")) {
        include_once(drupal_get_path('module', 'node') . '/node.pages.inc');
    }
    $output = drupal_get_form('review_node_form_' . $unique, $node);
    return $output;
}

function mymodule_forms($form_id, $args) {
    $forms = array();
    if (strpos($form_id, "review_node_form_") === 0) {
        $forms[$form_id] = array('callback' => 'node_form');
    }
    return $forms;
}


function mymodule_form_alter(&$form, $form_state, $form_id) {
    if (isset($form['type']) && isset($form['#node']) && $form_id != $form['type']['#value'] .'_node_form' && $form['type']['#value'] == 'review') {
        $type = content_types($form['#node']->type);
        if (!empty($type['fields'])) {
            module_load_include('inc', 'content', 'includes/content.node_form');
            $form = array_merge($form, content_form($form, $form_state));
        }
        $form['#pre_render'][] = 'content_alter_extra_weights';
        $form['#content_extra_fields'] = $type['extra'];

        //$form['#id'] = $form_id;
        //$form['#validate'][0] = $form_id . '_validate';

        $form['title']['#type'] = 'value';
        $form['field_review_to_A']['#type'] = 'value';
        $form['field_review_to_B']['#type'] = 'value';
        $form['field_review_to_profile']['#type'] = 'value';
    }
}

问题

我总结不清楚的问题......

  1. 这是在同一页面上显示多个节点表单的良好通用方法吗?
  2. 在功能content中复制/粘贴来自mymodule_form_alter模块content_form_alter功能的代码是否可以?如果content模块更新,它会不会制造东西吗?
  3. 我应该设置$form['#id']吗?没有它,所有表单都具有相同的HTML表单ID node_form,其ID是唯一的,如review_node_form_254。事实是,提交表单的方式没有区别。设置$form['#validate'][0]似乎也不会影响事情。也许我应该将$form[button]['#submit'][0]设置为其他内容?现在是node_form_submit
  4. 为什么验证即使使用唯一的表单ID和表单验证功能也不起作用?如果我在没有必填字段的情况下提交最后一个表单,则所有以前的表我应该自己做验证功能吗?什么级别 - 形式或领域?关于从哪里开始的任何提示?

3 个答案:

答案 0 :(得分:2)

您需要实现hook_forms()以将不同的ID映射到同一构建器函数。

您提到的NODETYPE_node_form ID已经是此机制的示例,因为它们都映射到节点模块node_form()实现中的相同构建器函数(node_forms())。

您可以在drupal_get_form()函数的“参数”说明中找到更多示例的链接。

答案 1 :(得分:1)

这对我非常有用。

关于所有drupal API的文档非常缺乏 - 我正在撕掉我的头发。对我而言,至关重要的一点,我不认为在网上的任何其他地方都有所涉及:

CCK通过hook_form_alter()将其字段添加到表单中。但它基于form_id来做到这一点。因此,如果表单ID不同(因为您希望在同一页面上有多个表单ID),则需要复制一些CCK代码以将字段添加到表单中。

这就是出色的表现。

答案 2 :(得分:0)

我真的没有挖到它的底部,但在我看来,你几乎完成了所有相关的挖掘工作。

根据我的理解仅通过检查代码,您认为content_form_alter()是显示阻止者是正确的。

也许这是一个天真的建议,但是从 content_form_alter()代码开始编写自己的hook_form_alter()实现,但是改变使更改发生的条件呢?我正在考虑这些问题:

function modulename_form_alter(&$form, $form_state, $form_id) {
  if (isset($form['type']) && isset($form['#node']) && 
  stripos($form_id, $form['type']['#value'] .'_node_form')) {
    ...
  }
}

我确实实际上测试了上面的代码,但我希望它是自我解释的:如果MYCCKTYPE_node_form是实际form_id的子字符串,您实际上会触发更改以获得自定义类型的内容( es:MYCCKTYPE_node_form_234)。

希望这至少有点帮助...祝你好运! :)

编辑:还有两件事

  1. 我刚刚想到,由于您的自定义实现hook_form_alter()将暂时不使用CCK,您需要添加一个检查以避免表单被修改两次,如:

    && $form_id != $form['type']['#value'] .'_node_form'

  2. 另一种方法是尝试通过不使用CCK但以编程方式实现自定义类型来实现这一点(如果您打算在各种不同的站点上使用模块,这甚至可能是一个优势。)

    < / LI>